diff options
Diffstat (limited to 'org.eclipse.jgit.test')
4 files changed, 879 insertions, 467 deletions
diff --git a/org.eclipse.jgit.test/pom.xml b/org.eclipse.jgit.test/pom.xml index dad1e3cacf..084014c61e 100644 --- a/org.eclipse.jgit.test/pom.xml +++ b/org.eclipse.jgit.test/pom.xml @@ -66,7 +66,6 @@ <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> - <scope>test</scope> </dependency> <!-- Optional security provider for encryption tests. --> diff --git a/org.eclipse.jgit.test/src/org/eclipse/jgit/events/ChangeRecorder.java b/org.eclipse.jgit.test/src/org/eclipse/jgit/events/ChangeRecorder.java new file mode 100644 index 0000000000..c5582a8601 --- /dev/null +++ b/org.eclipse.jgit.test/src/org/eclipse/jgit/events/ChangeRecorder.java @@ -0,0 +1,108 @@ +/* + * Copyright (C) 2017, Thomas Wolf <thomas.wolf@paranor.ch> + * and other copyright owners as documented in the project's IP log. + * + * This program and the accompanying materials are made available + * under the terms of the Eclipse Distribution License v1.0 which + * accompanies this distribution, is reproduced below, and is + * available at http://www.eclipse.org/org/documents/edl-v10.php + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * - Neither the name of the Eclipse Foundation, Inc. nor the + * names of its contributors may be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package org.eclipse.jgit.events; + +import static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertEquals; + +import java.util.Arrays; +import java.util.HashSet; +import java.util.Set; + +/** + * A {@link WorkingTreeModifiedListener} that can be used in tests to check + * expected events. + */ +public class ChangeRecorder implements WorkingTreeModifiedListener { + + public static final String[] EMPTY = new String[0]; + + private Set<String> modified = new HashSet<>(); + + private Set<String> deleted = new HashSet<>(); + + private int eventCount; + + @Override + public void onWorkingTreeModified(WorkingTreeModifiedEvent event) { + eventCount++; + modified.removeAll(event.getDeleted()); + deleted.removeAll(event.getModified()); + modified.addAll(event.getModified()); + deleted.addAll(event.getDeleted()); + } + + private String[] getModified() { + return modified.toArray(new String[modified.size()]); + } + + private String[] getDeleted() { + return deleted.toArray(new String[deleted.size()]); + } + + private void reset() { + eventCount = 0; + modified.clear(); + deleted.clear(); + } + + public void assertNoEvent() { + assertEquals("Unexpected WorkingTreeModifiedEvent ", 0, eventCount); + } + + public void assertEvent(String[] expectedModified, + String[] expectedDeleted) { + String[] actuallyModified = getModified(); + String[] actuallyDeleted = getDeleted(); + Arrays.sort(actuallyModified); + Arrays.sort(expectedModified); + Arrays.sort(actuallyDeleted); + Arrays.sort(expectedDeleted); + assertArrayEquals("Unexpected modifications reported", expectedModified, + actuallyModified); + assertArrayEquals("Unexpected deletions reported", expectedDeleted, + actuallyDeleted); + reset(); + } +} diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/StashApplyCommandTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/StashApplyCommandTest.java index f2e4d5b3b3..ad3ab7fbdf 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/StashApplyCommandTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/StashApplyCommandTest.java @@ -55,12 +55,15 @@ import org.eclipse.jgit.api.errors.InvalidRefNameException; import org.eclipse.jgit.api.errors.JGitInternalException; import org.eclipse.jgit.api.errors.NoHeadException; import org.eclipse.jgit.api.errors.StashApplyFailureException; +import org.eclipse.jgit.events.ChangeRecorder; +import org.eclipse.jgit.events.ListenerHandle; import org.eclipse.jgit.internal.JGitText; import org.eclipse.jgit.junit.RepositoryTestCase; import org.eclipse.jgit.lib.ObjectId; import org.eclipse.jgit.lib.Repository; import org.eclipse.jgit.revwalk.RevCommit; import org.eclipse.jgit.util.FileUtils; +import org.junit.After; import org.junit.Before; import org.junit.Test; @@ -77,15 +80,31 @@ public class StashApplyCommandTest extends RepositoryTestCase { private File committedFile; + private ChangeRecorder recorder; + + private ListenerHandle handle; + @Override @Before public void setUp() throws Exception { super.setUp(); git = Git.wrap(db); + recorder = new ChangeRecorder(); + handle = db.getListenerList().addWorkingTreeModifiedListener(recorder); committedFile = writeTrashFile(PATH, "content"); git.add().addFilepattern(PATH).call(); head = git.commit().setMessage("add file").call(); assertNotNull(head); + recorder.assertNoEvent(); + } + + @Override + @After + public void tearDown() throws Exception { + if (handle != null) { + handle.remove(); + } + super.tearDown(); } @Test @@ -95,10 +114,12 @@ public class StashApplyCommandTest extends RepositoryTestCase { RevCommit stashed = git.stashCreate().call(); assertNotNull(stashed); assertEquals("content", read(committedFile)); + recorder.assertEvent(new String[] { PATH }, ChangeRecorder.EMPTY); ObjectId unstashed = git.stashApply().call(); assertEquals(stashed, unstashed); assertFalse(committedFile.exists()); + recorder.assertEvent(ChangeRecorder.EMPTY, new String[] { PATH }); Status status = git.status().call(); assertTrue(status.getAdded().isEmpty()); @@ -121,11 +142,13 @@ public class StashApplyCommandTest extends RepositoryTestCase { RevCommit stashed = git.stashCreate().call(); assertNotNull(stashed); assertFalse(addedFile.exists()); + recorder.assertEvent(ChangeRecorder.EMPTY, new String[] { addedPath }); ObjectId unstashed = git.stashApply().call(); assertEquals(stashed, unstashed); assertTrue(addedFile.exists()); assertEquals("content2", read(addedFile)); + recorder.assertEvent(new String[] { addedPath }, ChangeRecorder.EMPTY); Status status = git.status().call(); assertTrue(status.getChanged().isEmpty()); @@ -142,14 +165,17 @@ public class StashApplyCommandTest extends RepositoryTestCase { @Test public void indexDelete() throws Exception { git.rm().addFilepattern("file.txt").call(); + recorder.assertEvent(ChangeRecorder.EMPTY, new String[] { "file.txt" }); RevCommit stashed = git.stashCreate().call(); assertNotNull(stashed); assertEquals("content", read(committedFile)); + recorder.assertEvent(new String[] { "file.txt" }, ChangeRecorder.EMPTY); ObjectId unstashed = git.stashApply().call(); assertEquals(stashed, unstashed); assertFalse(committedFile.exists()); + recorder.assertEvent(ChangeRecorder.EMPTY, new String[] { "file.txt" }); Status status = git.status().call(); assertTrue(status.getAdded().isEmpty()); @@ -170,10 +196,12 @@ public class StashApplyCommandTest extends RepositoryTestCase { RevCommit stashed = git.stashCreate().call(); assertNotNull(stashed); assertEquals("content", read(committedFile)); + recorder.assertEvent(new String[] { "file.txt" }, ChangeRecorder.EMPTY); ObjectId unstashed = git.stashApply().call(); assertEquals(stashed, unstashed); assertEquals("content2", read(committedFile)); + recorder.assertEvent(new String[] { "file.txt" }, ChangeRecorder.EMPTY); Status status = git.status().call(); assertTrue(status.getAdded().isEmpty()); @@ -193,16 +221,21 @@ public class StashApplyCommandTest extends RepositoryTestCase { File subfolderFile = writeTrashFile(path, "content"); git.add().addFilepattern(path).call(); head = git.commit().setMessage("add file").call(); + recorder.assertNoEvent(); writeTrashFile(path, "content2"); RevCommit stashed = git.stashCreate().call(); assertNotNull(stashed); assertEquals("content", read(subfolderFile)); + recorder.assertEvent(new String[] { "d1/d2/f.txt" }, + ChangeRecorder.EMPTY); ObjectId unstashed = git.stashApply().call(); assertEquals(stashed, unstashed); assertEquals("content2", read(subfolderFile)); + recorder.assertEvent(new String[] { "d1/d2/f.txt", "d1/d2", "d1" }, + ChangeRecorder.EMPTY); Status status = git.status().call(); assertTrue(status.getAdded().isEmpty()); @@ -225,10 +258,12 @@ public class StashApplyCommandTest extends RepositoryTestCase { RevCommit stashed = git.stashCreate().call(); assertNotNull(stashed); assertEquals("content", read(committedFile)); + recorder.assertEvent(new String[] { "file.txt" }, ChangeRecorder.EMPTY); ObjectId unstashed = git.stashApply().call(); assertEquals(stashed, unstashed); assertEquals("content3", read(committedFile)); + recorder.assertEvent(new String[] { "file.txt" }, ChangeRecorder.EMPTY); Status status = git.status().call(); assertTrue(status.getAdded().isEmpty()); @@ -252,10 +287,12 @@ public class StashApplyCommandTest extends RepositoryTestCase { RevCommit stashed = git.stashCreate().call(); assertNotNull(stashed); assertEquals("content", read(committedFile)); + recorder.assertEvent(new String[] { "file.txt" }, ChangeRecorder.EMPTY); ObjectId unstashed = git.stashApply().call(); assertEquals(stashed, unstashed); assertEquals("content2", read(committedFile)); + recorder.assertEvent(new String[] { "file.txt" }, ChangeRecorder.EMPTY); Status status = git.status().call(); assertTrue(status.getAdded().isEmpty()); @@ -281,10 +318,12 @@ public class StashApplyCommandTest extends RepositoryTestCase { RevCommit stashed = git.stashCreate().call(); assertNotNull(stashed); assertFalse(added.exists()); + recorder.assertNoEvent(); ObjectId unstashed = git.stashApply().call(); assertEquals(stashed, unstashed); assertEquals("content2", read(added)); + recorder.assertEvent(new String[] { path }, ChangeRecorder.EMPTY); Status status = git.status().call(); assertTrue(status.getChanged().isEmpty()); @@ -308,10 +347,12 @@ public class StashApplyCommandTest extends RepositoryTestCase { RevCommit stashed = git.stashCreate().call(); assertNotNull(stashed); assertEquals("content", read(committedFile)); + recorder.assertEvent(new String[] { PATH }, ChangeRecorder.EMPTY); ObjectId unstashed = git.stashApply().call(); assertEquals(stashed, unstashed); assertFalse(committedFile.exists()); + recorder.assertEvent(ChangeRecorder.EMPTY, new String[] { PATH }); Status status = git.status().call(); assertTrue(status.getAdded().isEmpty()); @@ -337,9 +378,13 @@ public class StashApplyCommandTest extends RepositoryTestCase { assertNotNull(stashed); assertTrue(committedFile.exists()); assertFalse(addedFile.exists()); + recorder.assertEvent(new String[] { PATH }, + new String[] { "file2.txt" }); ObjectId unstashed = git.stashApply().call(); assertEquals(stashed, unstashed); + recorder.assertEvent(new String[] { "file2.txt" }, + new String[] { PATH }); Status status = git.status().call(); assertTrue(status.getChanged().isEmpty()); @@ -362,6 +407,7 @@ public class StashApplyCommandTest extends RepositoryTestCase { assertNotNull(stashed); assertEquals("content", read(committedFile)); assertTrue(git.status().call().isClean()); + recorder.assertEvent(new String[] { PATH }, ChangeRecorder.EMPTY); writeTrashFile(PATH, "content3"); @@ -372,6 +418,7 @@ public class StashApplyCommandTest extends RepositoryTestCase { // expected } assertEquals("content3", read(PATH)); + recorder.assertNoEvent(); } @Test @@ -391,10 +438,12 @@ public class StashApplyCommandTest extends RepositoryTestCase { assertEquals("content\nhead change\nmore content\n", read(committedFile)); assertTrue(git.status().call().isClean()); + recorder.assertEvent(new String[] { PATH }, ChangeRecorder.EMPTY); writeTrashFile(PATH, "content\nmore content\ncommitted change\n"); git.add().addFilepattern(PATH).call(); git.commit().setMessage("committed change").call(); + recorder.assertNoEvent(); try { git.stashApply().call(); @@ -402,6 +451,7 @@ public class StashApplyCommandTest extends RepositoryTestCase { } catch (StashApplyFailureException e) { // expected } + recorder.assertEvent(new String[] { PATH }, ChangeRecorder.EMPTY); Status status = new StatusCommand(db).call(); assertEquals(1, status.getConflicting().size()); assertEquals( @@ -426,12 +476,15 @@ public class StashApplyCommandTest extends RepositoryTestCase { writeTrashFile(PATH, "master content"); git.add().addFilepattern(PATH).call(); git.commit().setMessage("even content").call(); + recorder.assertNoEvent(); git.checkout().setName(otherBranch).call(); + recorder.assertEvent(new String[] { PATH }, ChangeRecorder.EMPTY); writeTrashFile(PATH, "otherBranch content"); git.add().addFilepattern(PATH).call(); git.commit().setMessage("even more content").call(); + recorder.assertNoEvent(); writeTrashFile(path2, "content\nstashed change\nmore content\n"); @@ -442,12 +495,15 @@ public class StashApplyCommandTest extends RepositoryTestCase { assertEquals("otherBranch content", read(committedFile)); assertTrue(git.status().call().isClean()); + recorder.assertEvent(new String[] { path2 }, ChangeRecorder.EMPTY); git.checkout().setName("master").call(); + recorder.assertEvent(new String[] { PATH }, ChangeRecorder.EMPTY); git.stashApply().call(); assertEquals("content\nstashed change\nmore content\n", read(file2)); assertEquals("master content", read(committedFile)); + recorder.assertEvent(new String[] { path2 }, ChangeRecorder.EMPTY); } @Test @@ -467,12 +523,15 @@ public class StashApplyCommandTest extends RepositoryTestCase { writeTrashFile(PATH, "master content"); git.add().addFilepattern(PATH).call(); git.commit().setMessage("even content").call(); + recorder.assertNoEvent(); git.checkout().setName(otherBranch).call(); + recorder.assertEvent(new String[] { PATH }, ChangeRecorder.EMPTY); writeTrashFile(PATH, "otherBranch content"); git.add().addFilepattern(PATH).call(); git.commit().setMessage("even more content").call(); + recorder.assertNoEvent(); writeTrashFile(path2, "content\nstashed change in index\nmore content\n"); @@ -485,8 +544,10 @@ public class StashApplyCommandTest extends RepositoryTestCase { assertEquals("content\nmore content\n", read(file2)); assertEquals("otherBranch content", read(committedFile)); assertTrue(git.status().call().isClean()); + recorder.assertEvent(new String[] { path2 }, ChangeRecorder.EMPTY); git.checkout().setName("master").call(); + recorder.assertEvent(new String[] { PATH }, ChangeRecorder.EMPTY); git.stashApply().call(); assertEquals("content\nstashed change\nmore content\n", read(file2)); assertEquals( @@ -494,6 +555,7 @@ public class StashApplyCommandTest extends RepositoryTestCase { + "[file2.txt, mode:100644, content:content\nstashed change in index\nmore content\n]", indexState(CONTENT)); assertEquals("master content", read(committedFile)); + recorder.assertEvent(new String[] { path2 }, ChangeRecorder.EMPTY); } @Test @@ -501,6 +563,7 @@ public class StashApplyCommandTest extends RepositoryTestCase { writeTrashFile(PATH, "content\nmore content\n"); git.add().addFilepattern(PATH).call(); git.commit().setMessage("more content").call(); + recorder.assertNoEvent(); writeTrashFile(PATH, "content\nstashed change\nmore content\n"); @@ -508,15 +571,18 @@ public class StashApplyCommandTest extends RepositoryTestCase { assertNotNull(stashed); assertEquals("content\nmore content\n", read(committedFile)); assertTrue(git.status().call().isClean()); + recorder.assertEvent(new String[] { PATH }, ChangeRecorder.EMPTY); writeTrashFile(PATH, "content\nmore content\ncommitted change\n"); git.add().addFilepattern(PATH).call(); git.commit().setMessage("committed change").call(); + recorder.assertNoEvent(); git.stashApply().call(); assertEquals( "content\nstashed change\nmore content\ncommitted change\n", read(committedFile)); + recorder.assertEvent(new String[] { PATH }, ChangeRecorder.EMPTY); } @Test @@ -527,6 +593,7 @@ public class StashApplyCommandTest extends RepositoryTestCase { assertNotNull(stashed); assertEquals("content", read(committedFile)); assertTrue(git.status().call().isClean()); + recorder.assertEvent(new String[] { PATH }, ChangeRecorder.EMPTY); writeTrashFile(PATH, "content3"); git.add().addFilepattern(PATH).call(); @@ -538,6 +605,7 @@ public class StashApplyCommandTest extends RepositoryTestCase { } catch (StashApplyFailureException e) { // expected } + recorder.assertNoEvent(); assertEquals("content2", read(PATH)); } @@ -549,6 +617,7 @@ public class StashApplyCommandTest extends RepositoryTestCase { assertNotNull(stashed); assertEquals("content", read(committedFile)); assertTrue(git.status().call().isClean()); + recorder.assertEvent(new String[] { PATH }, ChangeRecorder.EMPTY); String path2 = "file2.txt"; writeTrashFile(path2, "content3"); @@ -557,6 +626,7 @@ public class StashApplyCommandTest extends RepositoryTestCase { ObjectId unstashed = git.stashApply().call(); assertEquals(stashed, unstashed); + recorder.assertEvent(new String[] { PATH }, ChangeRecorder.EMPTY); Status status = git.status().call(); assertTrue(status.getAdded().isEmpty()); @@ -583,12 +653,15 @@ public class StashApplyCommandTest extends RepositoryTestCase { RevCommit stashed = git.stashCreate().call(); assertNotNull(stashed); assertTrue(git.status().call().isClean()); + recorder.assertEvent(ChangeRecorder.EMPTY, + new String[] { subdir, path }); git.branchCreate().setName(otherBranch).call(); git.checkout().setName(otherBranch).call(); ObjectId unstashed = git.stashApply().call(); assertEquals(stashed, unstashed); + recorder.assertEvent(new String[] { path }, ChangeRecorder.EMPTY); Status status = git.status().call(); assertTrue(status.getChanged().isEmpty()); @@ -643,12 +716,15 @@ public class StashApplyCommandTest extends RepositoryTestCase { git.commit().setMessage("x").call(); file.delete(); git.rm().addFilepattern("file").call(); + recorder.assertNoEvent(); git.stashCreate().call(); + recorder.assertEvent(new String[] { "file" }, ChangeRecorder.EMPTY); file.delete(); git.stashApply().setStashRef("stash@{0}").call(); assertFalse(file.exists()); + recorder.assertEvent(ChangeRecorder.EMPTY, new String[] { "file" }); } @Test @@ -660,9 +736,11 @@ public class StashApplyCommandTest extends RepositoryTestCase { git.add().addFilepattern(PATH).call(); git.stashCreate().call(); assertTrue(untrackedFile.exists()); + recorder.assertEvent(new String[] { PATH }, ChangeRecorder.EMPTY); git.stashApply().setStashRef("stash@{0}").call(); assertTrue(untrackedFile.exists()); + recorder.assertEvent(new String[] { PATH }, ChangeRecorder.EMPTY); Status status = git.status().call(); assertEquals(1, status.getUntracked().size()); @@ -684,11 +762,14 @@ public class StashApplyCommandTest extends RepositoryTestCase { .call(); assertNotNull(stashedCommit); assertFalse(untrackedFile.exists()); + recorder.assertEvent(ChangeRecorder.EMPTY, new String[] { path }); + deleteTrashFile("a/b"); // checkout should create parent dirs git.stashApply().setStashRef("stash@{0}").call(); assertTrue(untrackedFile.exists()); assertEquals("content", read(path)); + recorder.assertEvent(new String[] { path }, ChangeRecorder.EMPTY); Status status = git.status().call(); assertEquals(1, status.getUntracked().size()); @@ -706,6 +787,7 @@ public class StashApplyCommandTest extends RepositoryTestCase { String path = "untracked.txt"; writeTrashFile(path, "untracked"); git.stashCreate().setIncludeUntracked(true).call(); + recorder.assertEvent(ChangeRecorder.EMPTY, new String[] { path }); writeTrashFile(path, "committed"); head = git.commit().setMessage("add file").call(); @@ -719,6 +801,7 @@ public class StashApplyCommandTest extends RepositoryTestCase { assertEquals(e.getMessage(), JGitText.get().stashApplyConflict); } assertEquals("committed", read(path)); + recorder.assertNoEvent(); } @Test @@ -727,6 +810,7 @@ public class StashApplyCommandTest extends RepositoryTestCase { String path = "untracked.txt"; writeTrashFile(path, "untracked"); git.stashCreate().setIncludeUntracked(true).call(); + recorder.assertEvent(ChangeRecorder.EMPTY, new String[] { path }); writeTrashFile(path, "working-directory"); try { @@ -736,6 +820,7 @@ public class StashApplyCommandTest extends RepositoryTestCase { assertEquals(e.getMessage(), JGitText.get().stashApplyConflict); } assertEquals("working-directory", read(path)); + recorder.assertNoEvent(); } @Test @@ -747,11 +832,13 @@ public class StashApplyCommandTest extends RepositoryTestCase { assertTrue(PATH + " should exist", check(PATH)); assertEquals(PATH + " should have been reset", "content", read(PATH)); assertFalse(path + " should not exist", check(path)); + recorder.assertEvent(new String[] { PATH }, new String[] { path }); git.stashApply().setStashRef("stash@{0}").call(); assertTrue(PATH + " should exist", check(PATH)); assertEquals(PATH + " should have new content", "changed", read(PATH)); assertTrue(path + " should exist", check(path)); assertEquals(path + " should have new content", "untracked", read(path)); + recorder.assertEvent(new String[] { PATH, path }, ChangeRecorder.EMPTY); } } diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/DirCacheCheckoutTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/DirCacheCheckoutTest.java index f8c2d4536d..05573b9468 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/DirCacheCheckoutTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/DirCacheCheckoutTest.java @@ -72,6 +72,8 @@ import org.eclipse.jgit.dircache.DirCacheEntry; import org.eclipse.jgit.errors.CheckoutConflictException; import org.eclipse.jgit.errors.CorruptObjectException; import org.eclipse.jgit.errors.NoWorkTreeException; +import org.eclipse.jgit.events.ChangeRecorder; +import org.eclipse.jgit.events.ListenerHandle; import org.eclipse.jgit.junit.RepositoryTestCase; import org.eclipse.jgit.junit.TestRepository; import org.eclipse.jgit.junit.TestRepository.BranchBuilder; @@ -141,14 +143,19 @@ public class DirCacheCheckoutTest extends RepositoryTestCase { @Test public void testResetHard() throws IOException, NoFilepatternException, GitAPIException { + ChangeRecorder recorder = new ChangeRecorder(); + ListenerHandle handle = null; try (Git git = new Git(db)) { + handle = db.getListenerList() + .addWorkingTreeModifiedListener(recorder); writeTrashFile("f", "f()"); writeTrashFile("D/g", "g()"); git.add().addFilepattern(".").call(); git.commit().setMessage("inital").call(); assertIndex(mkmap("f", "f()", "D/g", "g()")); - + recorder.assertNoEvent(); git.branchCreate().setName("topic").call(); + recorder.assertNoEvent(); writeTrashFile("f", "f()\nmaster"); writeTrashFile("D/g", "g()\ng2()"); @@ -156,9 +163,12 @@ public class DirCacheCheckoutTest extends RepositoryTestCase { git.add().addFilepattern(".").call(); RevCommit master = git.commit().setMessage("master-1").call(); assertIndex(mkmap("f", "f()\nmaster", "D/g", "g()\ng2()", "E/h", "h()")); + recorder.assertNoEvent(); checkoutBranch("refs/heads/topic"); assertIndex(mkmap("f", "f()", "D/g", "g()")); + recorder.assertEvent(new String[] { "f", "D/g" }, + new String[] { "E/h" }); writeTrashFile("f", "f()\nside"); assertTrue(new File(db.getWorkTree(), "D/g").delete()); @@ -167,26 +177,41 @@ public class DirCacheCheckoutTest extends RepositoryTestCase { git.add().addFilepattern(".").setUpdate(true).call(); RevCommit topic = git.commit().setMessage("topic-1").call(); assertIndex(mkmap("f", "f()\nside", "G/i", "i()")); + recorder.assertNoEvent(); writeTrashFile("untracked", "untracked"); resetHard(master); assertIndex(mkmap("f", "f()\nmaster", "D/g", "g()\ng2()", "E/h", "h()")); + recorder.assertEvent(new String[] { "f", "D/g", "E/h" }, + new String[] { "G", "G/i" }); + resetHard(topic); assertIndex(mkmap("f", "f()\nside", "G/i", "i()")); assertWorkDir(mkmap("f", "f()\nside", "G/i", "i()", "untracked", "untracked")); + recorder.assertEvent(new String[] { "f", "G/i" }, + new String[] { "D", "D/g", "E", "E/h" }); assertEquals(MergeStatus.CONFLICTING, git.merge().include(master) .call().getMergeStatus()); assertEquals( "[D/g, mode:100644, stage:1][D/g, mode:100644, stage:3][E/h, mode:100644][G/i, mode:100644][f, mode:100644, stage:1][f, mode:100644, stage:2][f, mode:100644, stage:3]", indexState(0)); + recorder.assertEvent(new String[] { "f", "D/g", "E/h" }, + ChangeRecorder.EMPTY); resetHard(master); assertIndex(mkmap("f", "f()\nmaster", "D/g", "g()\ng2()", "E/h", "h()")); assertWorkDir(mkmap("f", "f()\nmaster", "D/g", "g()\ng2()", "E/h", "h()", "untracked", "untracked")); + recorder.assertEvent(new String[] { "f", "D/g" }, + new String[] { "G", "G/i" }); + + } finally { + if (handle != null) { + handle.remove(); + } } } @@ -202,13 +227,18 @@ public class DirCacheCheckoutTest extends RepositoryTestCase { @Test public void testResetHardFromIndexEntryWithoutFileToTreeWithoutFile() throws Exception { + ChangeRecorder recorder = new ChangeRecorder(); + ListenerHandle handle = null; try (Git git = new Git(db)) { + handle = db.getListenerList() + .addWorkingTreeModifiedListener(recorder); writeTrashFile("x", "x"); git.add().addFilepattern("x").call(); RevCommit id1 = git.commit().setMessage("c1").call(); writeTrashFile("f/g", "f/g"); git.rm().addFilepattern("x").call(); + recorder.assertEvent(ChangeRecorder.EMPTY, new String[] { "x" }); git.add().addFilepattern("f/g").call(); git.commit().setMessage("c2").call(); deleteTrashFile("f/g"); @@ -217,6 +247,11 @@ public class DirCacheCheckoutTest extends RepositoryTestCase { // The actual test git.reset().setMode(ResetType.HARD).setRef(id1.getName()).call(); assertIndex(mkmap("x", "x")); + recorder.assertEvent(new String[] { "x" }, ChangeRecorder.EMPTY); + } finally { + if (handle != null) { + handle.remove(); + } } } @@ -227,13 +262,22 @@ public class DirCacheCheckoutTest extends RepositoryTestCase { */ @Test public void testInitialCheckout() throws Exception { + ChangeRecorder recorder = new ChangeRecorder(); + ListenerHandle handle = null; try (Git git = new Git(db)) { + handle = db.getListenerList() + .addWorkingTreeModifiedListener(recorder); TestRepository<Repository> db_t = new TestRepository<>(db); BranchBuilder master = db_t.branch("master"); master.commit().add("f", "1").message("m0").create(); assertFalse(new File(db.getWorkTree(), "f").exists()); git.checkout().setName("master").call(); assertTrue(new File(db.getWorkTree(), "f").exists()); + recorder.assertEvent(new String[] { "f" }, ChangeRecorder.EMPTY); + } finally { + if (handle != null) { + handle.remove(); + } } } @@ -930,120 +974,154 @@ public class DirCacheCheckoutTest extends RepositoryTestCase { public void testCheckoutChangeLinkToEmptyDir() throws Exception { Assume.assumeTrue(FS.DETECTED.supportsSymlinks()); String fname = "was_file"; - Git git = Git.wrap(db); - - // Add a file - writeTrashFile(fname, "a"); - git.add().addFilepattern(fname).call(); - - // Add a link to file - String linkName = "link"; - File link = writeLink(linkName, fname).toFile(); - git.add().addFilepattern(linkName).call(); - git.commit().setMessage("Added file and link").call(); - - assertWorkDir(mkmap(linkName, "a", fname, "a")); - - // replace link with empty directory - FileUtils.delete(link); - FileUtils.mkdir(link); - assertTrue("Link must be a directory now", link.isDirectory()); - - // modify file - writeTrashFile(fname, "b"); - assertWorkDir(mkmap(fname, "b", linkName, "/")); - - // revert both paths to HEAD state - git.checkout().setStartPoint(Constants.HEAD) - .addPath(fname).addPath(linkName).call(); - - assertWorkDir(mkmap(fname, "a", linkName, "a")); - - Status st = git.status().call(); - assertTrue(st.isClean()); + ChangeRecorder recorder = new ChangeRecorder(); + ListenerHandle handle = null; + try (Git git = new Git(db)) { + handle = db.getListenerList() + .addWorkingTreeModifiedListener(recorder); + // Add a file + writeTrashFile(fname, "a"); + git.add().addFilepattern(fname).call(); + + // Add a link to file + String linkName = "link"; + File link = writeLink(linkName, fname).toFile(); + git.add().addFilepattern(linkName).call(); + git.commit().setMessage("Added file and link").call(); + + assertWorkDir(mkmap(linkName, "a", fname, "a")); + + // replace link with empty directory + FileUtils.delete(link); + FileUtils.mkdir(link); + assertTrue("Link must be a directory now", link.isDirectory()); + + // modify file + writeTrashFile(fname, "b"); + assertWorkDir(mkmap(fname, "b", linkName, "/")); + recorder.assertNoEvent(); + + // revert both paths to HEAD state + git.checkout().setStartPoint(Constants.HEAD).addPath(fname) + .addPath(linkName).call(); + + assertWorkDir(mkmap(fname, "a", linkName, "a")); + recorder.assertEvent(new String[] { fname, linkName }, + ChangeRecorder.EMPTY); + + Status st = git.status().call(); + assertTrue(st.isClean()); + } finally { + if (handle != null) { + handle.remove(); + } + } } @Test public void testCheckoutChangeLinkToEmptyDirs() throws Exception { Assume.assumeTrue(FS.DETECTED.supportsSymlinks()); String fname = "was_file"; - Git git = Git.wrap(db); - - // Add a file - writeTrashFile(fname, "a"); - git.add().addFilepattern(fname).call(); - - // Add a link to file - String linkName = "link"; - File link = writeLink(linkName, fname).toFile(); - git.add().addFilepattern(linkName).call(); - git.commit().setMessage("Added file and link").call(); - - assertWorkDir(mkmap(linkName, "a", fname, "a")); - - // replace link with directory containing only directories, no files - FileUtils.delete(link); - FileUtils.mkdirs(new File(link, "dummyDir")); - assertTrue("Link must be a directory now", link.isDirectory()); - - assertFalse("Must not delete non empty directory", link.delete()); - - // modify file - writeTrashFile(fname, "b"); - assertWorkDir(mkmap(fname, "b", linkName + "/dummyDir", "/")); - - // revert both paths to HEAD state - git.checkout().setStartPoint(Constants.HEAD) - .addPath(fname).addPath(linkName).call(); - - assertWorkDir(mkmap(fname, "a", linkName, "a")); - - Status st = git.status().call(); - assertTrue(st.isClean()); + ChangeRecorder recorder = new ChangeRecorder(); + ListenerHandle handle = null; + try (Git git = new Git(db)) { + handle = db.getListenerList() + .addWorkingTreeModifiedListener(recorder); + // Add a file + writeTrashFile(fname, "a"); + git.add().addFilepattern(fname).call(); + + // Add a link to file + String linkName = "link"; + File link = writeLink(linkName, fname).toFile(); + git.add().addFilepattern(linkName).call(); + git.commit().setMessage("Added file and link").call(); + + assertWorkDir(mkmap(linkName, "a", fname, "a")); + + // replace link with directory containing only directories, no files + FileUtils.delete(link); + FileUtils.mkdirs(new File(link, "dummyDir")); + assertTrue("Link must be a directory now", link.isDirectory()); + + assertFalse("Must not delete non empty directory", link.delete()); + + // modify file + writeTrashFile(fname, "b"); + assertWorkDir(mkmap(fname, "b", linkName + "/dummyDir", "/")); + recorder.assertNoEvent(); + + // revert both paths to HEAD state + git.checkout().setStartPoint(Constants.HEAD).addPath(fname) + .addPath(linkName).call(); + + assertWorkDir(mkmap(fname, "a", linkName, "a")); + recorder.assertEvent(new String[] { fname, linkName }, + ChangeRecorder.EMPTY); + + Status st = git.status().call(); + assertTrue(st.isClean()); + } finally { + if (handle != null) { + handle.remove(); + } + } } @Test public void testCheckoutChangeLinkToNonEmptyDirs() throws Exception { Assume.assumeTrue(FS.DETECTED.supportsSymlinks()); String fname = "file"; - Git git = Git.wrap(db); - - // Add a file - writeTrashFile(fname, "a"); - git.add().addFilepattern(fname).call(); + ChangeRecorder recorder = new ChangeRecorder(); + ListenerHandle handle = null; + try (Git git = new Git(db)) { + handle = db.getListenerList() + .addWorkingTreeModifiedListener(recorder); + // Add a file + writeTrashFile(fname, "a"); + git.add().addFilepattern(fname).call(); - // Add a link to file - String linkName = "link"; - File link = writeLink(linkName, fname).toFile(); - git.add().addFilepattern(linkName).call(); - git.commit().setMessage("Added file and link").call(); + // Add a link to file + String linkName = "link"; + File link = writeLink(linkName, fname).toFile(); + git.add().addFilepattern(linkName).call(); + git.commit().setMessage("Added file and link").call(); - assertWorkDir(mkmap(linkName, "a", fname, "a")); + assertWorkDir(mkmap(linkName, "a", fname, "a")); - // replace link with directory containing only directories, no files - FileUtils.delete(link); + // replace link with directory containing only directories, no files + FileUtils.delete(link); - // create but do not add a file in the new directory to the index - writeTrashFile(linkName + "/dir1", "file1", "c"); + // create but do not add a file in the new directory to the index + writeTrashFile(linkName + "/dir1", "file1", "c"); - // create but do not add a file in the new directory to the index - writeTrashFile(linkName + "/dir2", "file2", "d"); + // create but do not add a file in the new directory to the index + writeTrashFile(linkName + "/dir2", "file2", "d"); - assertTrue("File must be a directory now", link.isDirectory()); - assertFalse("Must not delete non empty directory", link.delete()); + assertTrue("File must be a directory now", link.isDirectory()); + assertFalse("Must not delete non empty directory", link.delete()); - // 2 extra files are created - assertWorkDir(mkmap(fname, "a", linkName + "/dir1/file1", "c", - linkName + "/dir2/file2", "d")); + // 2 extra files are created + assertWorkDir(mkmap(fname, "a", linkName + "/dir1/file1", "c", + linkName + "/dir2/file2", "d")); + recorder.assertNoEvent(); - // revert path to HEAD state - git.checkout().setStartPoint(Constants.HEAD).addPath(linkName).call(); + // revert path to HEAD state + git.checkout().setStartPoint(Constants.HEAD).addPath(linkName) + .call(); - // expect only the one added to the index - assertWorkDir(mkmap(linkName, "a", fname, "a")); + // expect only the one added to the index + assertWorkDir(mkmap(linkName, "a", fname, "a")); + recorder.assertEvent(new String[] { linkName }, + ChangeRecorder.EMPTY); - Status st = git.status().call(); - assertTrue(st.isClean()); + Status st = git.status().call(); + assertTrue(st.isClean()); + } finally { + if (handle != null) { + handle.remove(); + } + } } @Test @@ -1051,174 +1129,222 @@ public class DirCacheCheckoutTest extends RepositoryTestCase { throws Exception { Assume.assumeTrue(FS.DETECTED.supportsSymlinks()); String fname = "file"; - Git git = Git.wrap(db); - - // Add a file - writeTrashFile(fname, "a"); - git.add().addFilepattern(fname).call(); + ChangeRecorder recorder = new ChangeRecorder(); + ListenerHandle handle = null; + try (Git git = new Git(db)) { + handle = db.getListenerList() + .addWorkingTreeModifiedListener(recorder); + // Add a file + writeTrashFile(fname, "a"); + git.add().addFilepattern(fname).call(); - // Add a link to file - String linkName = "link"; - File link = writeLink(linkName, fname).toFile(); - git.add().addFilepattern(linkName).call(); - git.commit().setMessage("Added file and link").call(); + // Add a link to file + String linkName = "link"; + File link = writeLink(linkName, fname).toFile(); + git.add().addFilepattern(linkName).call(); + git.commit().setMessage("Added file and link").call(); - assertWorkDir(mkmap(linkName, "a", fname, "a")); + assertWorkDir(mkmap(linkName, "a", fname, "a")); - // replace link with directory containing only directories, no files - FileUtils.delete(link); + // replace link with directory containing only directories, no files + FileUtils.delete(link); - // create and add a file in the new directory to the index - writeTrashFile(linkName + "/dir1", "file1", "c"); - git.add().addFilepattern(linkName + "/dir1/file1").call(); + // create and add a file in the new directory to the index + writeTrashFile(linkName + "/dir1", "file1", "c"); + git.add().addFilepattern(linkName + "/dir1/file1").call(); - // create but do not add a file in the new directory to the index - writeTrashFile(linkName + "/dir2", "file2", "d"); + // create but do not add a file in the new directory to the index + writeTrashFile(linkName + "/dir2", "file2", "d"); - assertTrue("File must be a directory now", link.isDirectory()); - assertFalse("Must not delete non empty directory", link.delete()); + assertTrue("File must be a directory now", link.isDirectory()); + assertFalse("Must not delete non empty directory", link.delete()); - // 2 extra files are created - assertWorkDir(mkmap(fname, "a", linkName + "/dir1/file1", "c", - linkName + "/dir2/file2", "d")); + // 2 extra files are created + assertWorkDir(mkmap(fname, "a", linkName + "/dir1/file1", "c", + linkName + "/dir2/file2", "d")); + recorder.assertNoEvent(); - // revert path to HEAD state - git.checkout().setStartPoint(Constants.HEAD).addPath(linkName).call(); + // revert path to HEAD state + git.checkout().setStartPoint(Constants.HEAD).addPath(linkName) + .call(); - // original file and link - assertWorkDir(mkmap(linkName, "a", fname, "a")); + // original file and link + assertWorkDir(mkmap(linkName, "a", fname, "a")); + recorder.assertEvent(new String[] { linkName }, + ChangeRecorder.EMPTY); - Status st = git.status().call(); - assertTrue(st.isClean()); + Status st = git.status().call(); + assertTrue(st.isClean()); + } finally { + if (handle != null) { + handle.remove(); + } + } } @Test public void testCheckoutChangeFileToEmptyDir() throws Exception { String fname = "was_file"; - Git git = Git.wrap(db); - - // Add a file - File file = writeTrashFile(fname, "a"); - git.add().addFilepattern(fname).call(); - git.commit().setMessage("Added file").call(); - - // replace file with empty directory - FileUtils.delete(file); - FileUtils.mkdir(file); - assertTrue("File must be a directory now", file.isDirectory()); - - assertWorkDir(mkmap(fname, "/")); - - // revert path to HEAD state - git.checkout().setStartPoint(Constants.HEAD).addPath(fname).call(); - - assertWorkDir(mkmap(fname, "a")); - - Status st = git.status().call(); - assertTrue(st.isClean()); + ChangeRecorder recorder = new ChangeRecorder(); + ListenerHandle handle = null; + try (Git git = new Git(db)) { + handle = db.getListenerList() + .addWorkingTreeModifiedListener(recorder); + // Add a file + File file = writeTrashFile(fname, "a"); + git.add().addFilepattern(fname).call(); + git.commit().setMessage("Added file").call(); + + // replace file with empty directory + FileUtils.delete(file); + FileUtils.mkdir(file); + assertTrue("File must be a directory now", file.isDirectory()); + assertWorkDir(mkmap(fname, "/")); + recorder.assertNoEvent(); + + // revert path to HEAD state + git.checkout().setStartPoint(Constants.HEAD).addPath(fname).call(); + assertWorkDir(mkmap(fname, "a")); + recorder.assertEvent(new String[] { fname }, ChangeRecorder.EMPTY); + + Status st = git.status().call(); + assertTrue(st.isClean()); + } finally { + if (handle != null) { + handle.remove(); + } + } } @Test public void testCheckoutChangeFileToEmptyDirs() throws Exception { String fname = "was_file"; - Git git = Git.wrap(db); - - // Add a file - File file = writeTrashFile(fname, "a"); - git.add().addFilepattern(fname).call(); - git.commit().setMessage("Added file").call(); - - // replace file with directory containing only directories, no files - FileUtils.delete(file); - FileUtils.mkdirs(new File(file, "dummyDir")); - assertTrue("File must be a directory now", file.isDirectory()); - assertFalse("Must not delete non empty directory", file.delete()); - - assertWorkDir(mkmap(fname + "/dummyDir", "/")); - - // revert path to HEAD state - git.checkout().setStartPoint(Constants.HEAD).addPath(fname).call(); - - assertWorkDir(mkmap(fname, "a")); - - Status st = git.status().call(); - assertTrue(st.isClean()); + ChangeRecorder recorder = new ChangeRecorder(); + ListenerHandle handle = null; + try (Git git = new Git(db)) { + handle = db.getListenerList() + .addWorkingTreeModifiedListener(recorder); + // Add a file + File file = writeTrashFile(fname, "a"); + git.add().addFilepattern(fname).call(); + git.commit().setMessage("Added file").call(); + + // replace file with directory containing only directories, no files + FileUtils.delete(file); + FileUtils.mkdirs(new File(file, "dummyDir")); + assertTrue("File must be a directory now", file.isDirectory()); + assertFalse("Must not delete non empty directory", file.delete()); + + assertWorkDir(mkmap(fname + "/dummyDir", "/")); + recorder.assertNoEvent(); + + // revert path to HEAD state + git.checkout().setStartPoint(Constants.HEAD).addPath(fname).call(); + assertWorkDir(mkmap(fname, "a")); + recorder.assertEvent(new String[] { fname }, ChangeRecorder.EMPTY); + + Status st = git.status().call(); + assertTrue(st.isClean()); + } finally { + if (handle != null) { + handle.remove(); + } + } } @Test public void testCheckoutChangeFileToNonEmptyDirs() throws Exception { String fname = "was_file"; - Git git = Git.wrap(db); - - // Add a file - File file = writeTrashFile(fname, "a"); - git.add().addFilepattern(fname).call(); - git.commit().setMessage("Added file").call(); + ChangeRecorder recorder = new ChangeRecorder(); + ListenerHandle handle = null; + try (Git git = new Git(db)) { + handle = db.getListenerList() + .addWorkingTreeModifiedListener(recorder); + // Add a file + File file = writeTrashFile(fname, "a"); + git.add().addFilepattern(fname).call(); + git.commit().setMessage("Added file").call(); - assertWorkDir(mkmap(fname, "a")); + assertWorkDir(mkmap(fname, "a")); - // replace file with directory containing only directories, no files - FileUtils.delete(file); + // replace file with directory containing only directories, no files + FileUtils.delete(file); - // create but do not add a file in the new directory to the index - writeTrashFile(fname + "/dir1", "file1", "c"); + // create but do not add a file in the new directory to the index + writeTrashFile(fname + "/dir1", "file1", "c"); - // create but do not add a file in the new directory to the index - writeTrashFile(fname + "/dir2", "file2", "d"); + // create but do not add a file in the new directory to the index + writeTrashFile(fname + "/dir2", "file2", "d"); - assertTrue("File must be a directory now", file.isDirectory()); - assertFalse("Must not delete non empty directory", file.delete()); + assertTrue("File must be a directory now", file.isDirectory()); + assertFalse("Must not delete non empty directory", file.delete()); - // 2 extra files are created - assertWorkDir( - mkmap(fname + "/dir1/file1", "c", fname + "/dir2/file2", "d")); + // 2 extra files are created + assertWorkDir(mkmap(fname + "/dir1/file1", "c", + fname + "/dir2/file2", "d")); + recorder.assertNoEvent(); - // revert path to HEAD state - git.checkout().setStartPoint(Constants.HEAD).addPath(fname).call(); + // revert path to HEAD state + git.checkout().setStartPoint(Constants.HEAD).addPath(fname).call(); - // expect only the one added to the index - assertWorkDir(mkmap(fname, "a")); + // expect only the one added to the index + assertWorkDir(mkmap(fname, "a")); + recorder.assertEvent(new String[] { fname }, ChangeRecorder.EMPTY); - Status st = git.status().call(); - assertTrue(st.isClean()); + Status st = git.status().call(); + assertTrue(st.isClean()); + } finally { + if (handle != null) { + handle.remove(); + } + } } @Test public void testCheckoutChangeFileToNonEmptyDirsAndNewIndexEntry() throws Exception { String fname = "was_file"; - Git git = Git.wrap(db); - - // Add a file - File file = writeTrashFile(fname, "a"); - git.add().addFilepattern(fname).call(); - git.commit().setMessage("Added file").call(); - - assertWorkDir(mkmap(fname, "a")); - - // replace file with directory containing only directories, no files - FileUtils.delete(file); - - // create and add a file in the new directory to the index - writeTrashFile(fname + "/dir", "file1", "c"); - git.add().addFilepattern(fname + "/dir/file1").call(); - - // create but do not add a file in the new directory to the index - writeTrashFile(fname + "/dir", "file2", "d"); - - assertTrue("File must be a directory now", file.isDirectory()); - assertFalse("Must not delete non empty directory", file.delete()); - - // 2 extra files are created - assertWorkDir( - mkmap(fname + "/dir/file1", "c", fname + "/dir/file2", "d")); - - // revert path to HEAD state - git.checkout().setStartPoint(Constants.HEAD).addPath(fname).call(); - assertWorkDir(mkmap(fname, "a")); - - Status st = git.status().call(); - assertTrue(st.isClean()); + ChangeRecorder recorder = new ChangeRecorder(); + ListenerHandle handle = null; + try (Git git = new Git(db)) { + handle = db.getListenerList() + .addWorkingTreeModifiedListener(recorder); + // Add a file + File file = writeTrashFile(fname, "a"); + git.add().addFilepattern(fname).call(); + git.commit().setMessage("Added file").call(); + + assertWorkDir(mkmap(fname, "a")); + + // replace file with directory containing only directories, no files + FileUtils.delete(file); + + // create and add a file in the new directory to the index + writeTrashFile(fname + "/dir", "file1", "c"); + git.add().addFilepattern(fname + "/dir/file1").call(); + + // create but do not add a file in the new directory to the index + writeTrashFile(fname + "/dir", "file2", "d"); + + assertTrue("File must be a directory now", file.isDirectory()); + assertFalse("Must not delete non empty directory", file.delete()); + + // 2 extra files are created + assertWorkDir(mkmap(fname + "/dir/file1", "c", fname + "/dir/file2", + "d")); + recorder.assertNoEvent(); + + // revert path to HEAD state + git.checkout().setStartPoint(Constants.HEAD).addPath(fname).call(); + assertWorkDir(mkmap(fname, "a")); + recorder.assertEvent(new String[] { fname }, ChangeRecorder.EMPTY); + Status st = git.status().call(); + assertTrue(st.isClean()); + } finally { + if (handle != null) { + handle.remove(); + } + } } @Test @@ -1293,76 +1419,100 @@ public class DirCacheCheckoutTest extends RepositoryTestCase { public void testOverwriteUntrackedIgnoredFile() throws IOException, GitAPIException { String fname="file.txt"; - Git git = Git.wrap(db); - - // Add a file - writeTrashFile(fname, "a"); - git.add().addFilepattern(fname).call(); - git.commit().setMessage("create file").call(); - - // Create branch - git.branchCreate().setName("side").call(); - - // Modify file - writeTrashFile(fname, "b"); - git.add().addFilepattern(fname).call(); - git.commit().setMessage("modify file").call(); - - // Switch branches - git.checkout().setName("side").call(); - git.rm().addFilepattern(fname).call(); - writeTrashFile(".gitignore", fname); - git.add().addFilepattern(".gitignore").call(); - git.commit().setMessage("delete and ignore file").call(); - - writeTrashFile(fname, "Something different"); - git.checkout().setName("master").call(); - assertWorkDir(mkmap(fname, "b")); - assertTrue(git.status().call().isClean()); + ChangeRecorder recorder = new ChangeRecorder(); + ListenerHandle handle = null; + try (Git git = new Git(db)) { + handle = db.getListenerList() + .addWorkingTreeModifiedListener(recorder); + // Add a file + writeTrashFile(fname, "a"); + git.add().addFilepattern(fname).call(); + git.commit().setMessage("create file").call(); + + // Create branch + git.branchCreate().setName("side").call(); + + // Modify file + writeTrashFile(fname, "b"); + git.add().addFilepattern(fname).call(); + git.commit().setMessage("modify file").call(); + recorder.assertNoEvent(); + + // Switch branches + git.checkout().setName("side").call(); + recorder.assertEvent(new String[] { fname }, ChangeRecorder.EMPTY); + git.rm().addFilepattern(fname).call(); + recorder.assertEvent(ChangeRecorder.EMPTY, new String[] { fname }); + writeTrashFile(".gitignore", fname); + git.add().addFilepattern(".gitignore").call(); + git.commit().setMessage("delete and ignore file").call(); + + writeTrashFile(fname, "Something different"); + recorder.assertNoEvent(); + git.checkout().setName("master").call(); + assertWorkDir(mkmap(fname, "b")); + recorder.assertEvent(new String[] { fname }, + new String[] { ".gitignore" }); + assertTrue(git.status().call().isClean()); + } finally { + if (handle != null) { + handle.remove(); + } + } } @Test public void testOverwriteUntrackedFileModeChange() throws IOException, GitAPIException { String fname = "file.txt"; - Git git = Git.wrap(db); - - // Add a file - File file = writeTrashFile(fname, "a"); - git.add().addFilepattern(fname).call(); - git.commit().setMessage("create file").call(); - assertWorkDir(mkmap(fname, "a")); - - // Create branch - git.branchCreate().setName("side").call(); + ChangeRecorder recorder = new ChangeRecorder(); + ListenerHandle handle = null; + try (Git git = new Git(db)) { + handle = db.getListenerList() + .addWorkingTreeModifiedListener(recorder); + // Add a file + File file = writeTrashFile(fname, "a"); + git.add().addFilepattern(fname).call(); + git.commit().setMessage("create file").call(); + assertWorkDir(mkmap(fname, "a")); - // Switch branches - git.checkout().setName("side").call(); + // Create branch + git.branchCreate().setName("side").call(); - // replace file with directory containing files - FileUtils.delete(file); + // Switch branches + git.checkout().setName("side").call(); + recorder.assertNoEvent(); - // create and add a file in the new directory to the index - writeTrashFile(fname + "/dir1", "file1", "c"); - git.add().addFilepattern(fname + "/dir1/file1").call(); + // replace file with directory containing files + FileUtils.delete(file); - // create but do not add a file in the new directory to the index - writeTrashFile(fname + "/dir2", "file2", "d"); + // create and add a file in the new directory to the index + writeTrashFile(fname + "/dir1", "file1", "c"); + git.add().addFilepattern(fname + "/dir1/file1").call(); - assertTrue("File must be a directory now", file.isDirectory()); - assertFalse("Must not delete non empty directory", file.delete()); + // create but do not add a file in the new directory to the index + writeTrashFile(fname + "/dir2", "file2", "d"); - // 2 extra files are created - assertWorkDir( - mkmap(fname + "/dir1/file1", "c", fname + "/dir2/file2", "d")); + assertTrue("File must be a directory now", file.isDirectory()); + assertFalse("Must not delete non empty directory", file.delete()); - try { - git.checkout().setName("master").call(); - fail("did not throw exception"); - } catch (Exception e) { - // 2 extra files are still there + // 2 extra files are created assertWorkDir(mkmap(fname + "/dir1/file1", "c", fname + "/dir2/file2", "d")); + + try { + git.checkout().setName("master").call(); + fail("did not throw exception"); + } catch (Exception e) { + // 2 extra files are still there + assertWorkDir(mkmap(fname + "/dir1/file1", "c", + fname + "/dir2/file2", "d")); + } + recorder.assertNoEvent(); + } finally { + if (handle != null) { + handle.remove(); + } } } @@ -1371,50 +1521,60 @@ public class DirCacheCheckoutTest extends RepositoryTestCase { throws Exception { Assume.assumeTrue(FS.DETECTED.supportsSymlinks()); String fname = "file.txt"; - Git git = Git.wrap(db); - - // Add a file - writeTrashFile(fname, "a"); - git.add().addFilepattern(fname).call(); - - // Add a link to file - String linkName = "link"; - File link = writeLink(linkName, fname).toFile(); - git.add().addFilepattern(linkName).call(); - git.commit().setMessage("Added file and link").call(); + ChangeRecorder recorder = new ChangeRecorder(); + ListenerHandle handle = null; + try (Git git = new Git(db)) { + handle = db.getListenerList() + .addWorkingTreeModifiedListener(recorder); + // Add a file + writeTrashFile(fname, "a"); + git.add().addFilepattern(fname).call(); - assertWorkDir(mkmap(linkName, "a", fname, "a")); + // Add a link to file + String linkName = "link"; + File link = writeLink(linkName, fname).toFile(); + git.add().addFilepattern(linkName).call(); + git.commit().setMessage("Added file and link").call(); - // Create branch - git.branchCreate().setName("side").call(); + assertWorkDir(mkmap(linkName, "a", fname, "a")); - // Switch branches - git.checkout().setName("side").call(); + // Create branch + git.branchCreate().setName("side").call(); - // replace link with directory containing files - FileUtils.delete(link); + // Switch branches + git.checkout().setName("side").call(); + recorder.assertNoEvent(); - // create and add a file in the new directory to the index - writeTrashFile(linkName + "/dir1", "file1", "c"); - git.add().addFilepattern(linkName + "/dir1/file1").call(); + // replace link with directory containing files + FileUtils.delete(link); - // create but do not add a file in the new directory to the index - writeTrashFile(linkName + "/dir2", "file2", "d"); + // create and add a file in the new directory to the index + writeTrashFile(linkName + "/dir1", "file1", "c"); + git.add().addFilepattern(linkName + "/dir1/file1").call(); - assertTrue("Link must be a directory now", link.isDirectory()); - assertFalse("Must not delete non empty directory", link.delete()); + // create but do not add a file in the new directory to the index + writeTrashFile(linkName + "/dir2", "file2", "d"); - // 2 extra files are created - assertWorkDir(mkmap(fname, "a", linkName + "/dir1/file1", "c", - linkName + "/dir2/file2", "d")); + assertTrue("Link must be a directory now", link.isDirectory()); + assertFalse("Must not delete non empty directory", link.delete()); - try { - git.checkout().setName("master").call(); - fail("did not throw exception"); - } catch (Exception e) { - // 2 extra files are still there + // 2 extra files are created assertWorkDir(mkmap(fname, "a", linkName + "/dir1/file1", "c", linkName + "/dir2/file2", "d")); + + try { + git.checkout().setName("master").call(); + fail("did not throw exception"); + } catch (Exception e) { + // 2 extra files are still there + assertWorkDir(mkmap(fname, "a", linkName + "/dir1/file1", "c", + linkName + "/dir2/file2", "d")); + } + recorder.assertNoEvent(); + } finally { + if (handle != null) { + handle.remove(); + } } } @@ -1423,36 +1583,47 @@ public class DirCacheCheckoutTest extends RepositoryTestCase { if (!FS.DETECTED.supportsExecute()) return; - Git git = Git.wrap(db); - - // Add non-executable file - File file = writeTrashFile("file.txt", "a"); - git.add().addFilepattern("file.txt").call(); - git.commit().setMessage("commit1").call(); - assertFalse(db.getFS().canExecute(file)); - - // Create branch - git.branchCreate().setName("b1").call(); - - // Make file executable - db.getFS().setExecute(file, true); - git.add().addFilepattern("file.txt").call(); - git.commit().setMessage("commit2").call(); - - // Verify executable and working directory is clean - Status status = git.status().call(); - assertTrue(status.getModified().isEmpty()); - assertTrue(status.getChanged().isEmpty()); - assertTrue(db.getFS().canExecute(file)); - - // Switch branches - git.checkout().setName("b1").call(); - - // Verify not executable and working directory is clean - status = git.status().call(); - assertTrue(status.getModified().isEmpty()); - assertTrue(status.getChanged().isEmpty()); - assertFalse(db.getFS().canExecute(file)); + ChangeRecorder recorder = new ChangeRecorder(); + ListenerHandle handle = null; + try (Git git = new Git(db)) { + handle = db.getListenerList() + .addWorkingTreeModifiedListener(recorder); + // Add non-executable file + File file = writeTrashFile("file.txt", "a"); + git.add().addFilepattern("file.txt").call(); + git.commit().setMessage("commit1").call(); + assertFalse(db.getFS().canExecute(file)); + + // Create branch + git.branchCreate().setName("b1").call(); + + // Make file executable + db.getFS().setExecute(file, true); + git.add().addFilepattern("file.txt").call(); + git.commit().setMessage("commit2").call(); + recorder.assertNoEvent(); + + // Verify executable and working directory is clean + Status status = git.status().call(); + assertTrue(status.getModified().isEmpty()); + assertTrue(status.getChanged().isEmpty()); + assertTrue(db.getFS().canExecute(file)); + + // Switch branches + git.checkout().setName("b1").call(); + + // Verify not executable and working directory is clean + status = git.status().call(); + assertTrue(status.getModified().isEmpty()); + assertTrue(status.getChanged().isEmpty()); + assertFalse(db.getFS().canExecute(file)); + recorder.assertEvent(new String[] { "file.txt" }, + ChangeRecorder.EMPTY); + } finally { + if (handle != null) { + handle.remove(); + } + } } @Test @@ -1460,41 +1631,50 @@ public class DirCacheCheckoutTest extends RepositoryTestCase { if (!FS.DETECTED.supportsExecute()) return; - Git git = Git.wrap(db); - - // Add non-executable file - File file = writeTrashFile("file.txt", "a"); - git.add().addFilepattern("file.txt").call(); - git.commit().setMessage("commit1").call(); - assertFalse(db.getFS().canExecute(file)); - - // Create branch - git.branchCreate().setName("b1").call(); - - // Make file executable - db.getFS().setExecute(file, true); - git.add().addFilepattern("file.txt").call(); - git.commit().setMessage("commit2").call(); - - // Verify executable and working directory is clean - Status status = git.status().call(); - assertTrue(status.getModified().isEmpty()); - assertTrue(status.getChanged().isEmpty()); - assertTrue(db.getFS().canExecute(file)); - - writeTrashFile("file.txt", "b"); - - // Switch branches - CheckoutCommand checkout = git.checkout().setName("b1"); - try { - checkout.call(); - fail("Checkout exception not thrown"); - } catch (org.eclipse.jgit.api.errors.CheckoutConflictException e) { - CheckoutResult result = checkout.getResult(); - assertNotNull(result); - assertNotNull(result.getConflictList()); - assertEquals(1, result.getConflictList().size()); - assertTrue(result.getConflictList().contains("file.txt")); + ChangeRecorder recorder = new ChangeRecorder(); + ListenerHandle handle = null; + try (Git git = new Git(db)) { + handle = db.getListenerList() + .addWorkingTreeModifiedListener(recorder); + // Add non-executable file + File file = writeTrashFile("file.txt", "a"); + git.add().addFilepattern("file.txt").call(); + git.commit().setMessage("commit1").call(); + assertFalse(db.getFS().canExecute(file)); + + // Create branch + git.branchCreate().setName("b1").call(); + + // Make file executable + db.getFS().setExecute(file, true); + git.add().addFilepattern("file.txt").call(); + git.commit().setMessage("commit2").call(); + + // Verify executable and working directory is clean + Status status = git.status().call(); + assertTrue(status.getModified().isEmpty()); + assertTrue(status.getChanged().isEmpty()); + assertTrue(db.getFS().canExecute(file)); + + writeTrashFile("file.txt", "b"); + + // Switch branches + CheckoutCommand checkout = git.checkout().setName("b1"); + try { + checkout.call(); + fail("Checkout exception not thrown"); + } catch (org.eclipse.jgit.api.errors.CheckoutConflictException e) { + CheckoutResult result = checkout.getResult(); + assertNotNull(result); + assertNotNull(result.getConflictList()); + assertEquals(1, result.getConflictList().size()); + assertTrue(result.getConflictList().contains("file.txt")); + } + recorder.assertNoEvent(); + } finally { + if (handle != null) { + handle.remove(); + } } } @@ -1504,40 +1684,52 @@ public class DirCacheCheckoutTest extends RepositoryTestCase { if (!FS.DETECTED.supportsExecute()) return; - Git git = Git.wrap(db); - - // Add non-executable file - File file = writeTrashFile("file.txt", "a"); - git.add().addFilepattern("file.txt").call(); - git.commit().setMessage("commit1").call(); - assertFalse(db.getFS().canExecute(file)); - - // Create branch - git.branchCreate().setName("b1").call(); - - // Create second commit and don't touch file - writeTrashFile("file2.txt", ""); - git.add().addFilepattern("file2.txt").call(); - git.commit().setMessage("commit2").call(); - - // stage a mode change - writeTrashFile("file.txt", "a"); - db.getFS().setExecute(file, true); - git.add().addFilepattern("file.txt").call(); - - // dirty the file - writeTrashFile("file.txt", "b"); - - assertEquals( - "[file.txt, mode:100755, content:a][file2.txt, mode:100644, content:]", - indexState(CONTENT)); - assertWorkDir(mkmap("file.txt", "b", "file2.txt", "")); + ChangeRecorder recorder = new ChangeRecorder(); + ListenerHandle handle = null; + try (Git git = new Git(db)) { + handle = db.getListenerList() + .addWorkingTreeModifiedListener(recorder); + // Add non-executable file + File file = writeTrashFile("file.txt", "a"); + git.add().addFilepattern("file.txt").call(); + git.commit().setMessage("commit1").call(); + assertFalse(db.getFS().canExecute(file)); + + // Create branch + git.branchCreate().setName("b1").call(); + + // Create second commit and don't touch file + writeTrashFile("file2.txt", ""); + git.add().addFilepattern("file2.txt").call(); + git.commit().setMessage("commit2").call(); + + // stage a mode change + writeTrashFile("file.txt", "a"); + db.getFS().setExecute(file, true); + git.add().addFilepattern("file.txt").call(); + + // dirty the file + writeTrashFile("file.txt", "b"); - // Switch branches and check that the dirty file survived in worktree - // and index - git.checkout().setName("b1").call(); - assertEquals("[file.txt, mode:100755, content:a]", indexState(CONTENT)); - assertWorkDir(mkmap("file.txt", "b")); + assertEquals( + "[file.txt, mode:100755, content:a][file2.txt, mode:100644, content:]", + indexState(CONTENT)); + assertWorkDir(mkmap("file.txt", "b", "file2.txt", "")); + recorder.assertNoEvent(); + + // Switch branches and check that the dirty file survived in + // worktree and index + git.checkout().setName("b1").call(); + assertEquals("[file.txt, mode:100755, content:a]", + indexState(CONTENT)); + assertWorkDir(mkmap("file.txt", "b")); + recorder.assertEvent(ChangeRecorder.EMPTY, + new String[] { "file2.txt" }); + } finally { + if (handle != null) { + handle.remove(); + } + } } @Test @@ -1546,40 +1738,53 @@ public class DirCacheCheckoutTest extends RepositoryTestCase { if (!FS.DETECTED.supportsExecute()) return; - Git git = Git.wrap(db); - - // Add non-executable file - File file = writeTrashFile("file.txt", "a"); - git.add().addFilepattern("file.txt").call(); - git.commit().setMessage("commit1").call(); - assertFalse(db.getFS().canExecute(file)); - - // Create branch - git.branchCreate().setName("b1").call(); - - // Create second commit with executable file - file = writeTrashFile("file.txt", "b"); - db.getFS().setExecute(file, true); - git.add().addFilepattern("file.txt").call(); - git.commit().setMessage("commit2").call(); - - // stage the same content as in the branch we want to switch to - writeTrashFile("file.txt", "a"); - db.getFS().setExecute(file, false); - git.add().addFilepattern("file.txt").call(); - - // dirty the file - writeTrashFile("file.txt", "c"); - db.getFS().setExecute(file, true); - - assertEquals("[file.txt, mode:100644, content:a]", indexState(CONTENT)); - assertWorkDir(mkmap("file.txt", "c")); - - // Switch branches and check that the dirty file survived in worktree - // and index - git.checkout().setName("b1").call(); - assertEquals("[file.txt, mode:100644, content:a]", indexState(CONTENT)); - assertWorkDir(mkmap("file.txt", "c")); + ChangeRecorder recorder = new ChangeRecorder(); + ListenerHandle handle = null; + try (Git git = new Git(db)) { + handle = db.getListenerList() + .addWorkingTreeModifiedListener(recorder); + // Add non-executable file + File file = writeTrashFile("file.txt", "a"); + git.add().addFilepattern("file.txt").call(); + git.commit().setMessage("commit1").call(); + assertFalse(db.getFS().canExecute(file)); + + // Create branch + git.branchCreate().setName("b1").call(); + + // Create second commit with executable file + file = writeTrashFile("file.txt", "b"); + db.getFS().setExecute(file, true); + git.add().addFilepattern("file.txt").call(); + git.commit().setMessage("commit2").call(); + + // stage the same content as in the branch we want to switch to + writeTrashFile("file.txt", "a"); + db.getFS().setExecute(file, false); + git.add().addFilepattern("file.txt").call(); + + // dirty the file + writeTrashFile("file.txt", "c"); + db.getFS().setExecute(file, true); + + assertEquals("[file.txt, mode:100644, content:a]", + indexState(CONTENT)); + assertWorkDir(mkmap("file.txt", "c")); + recorder.assertNoEvent(); + + // Switch branches and check that the dirty file survived in + // worktree + // and index + git.checkout().setName("b1").call(); + assertEquals("[file.txt, mode:100644, content:a]", + indexState(CONTENT)); + assertWorkDir(mkmap("file.txt", "c")); + recorder.assertNoEvent(); + } finally { + if (handle != null) { + handle.remove(); + } + } } @Test @@ -1587,31 +1792,44 @@ public class DirCacheCheckoutTest extends RepositoryTestCase { if (!FS.DETECTED.supportsExecute()) return; - Git git = Git.wrap(db); - - // Add first file - File file1 = writeTrashFile("file1.txt", "a"); - git.add().addFilepattern("file1.txt").call(); - git.commit().setMessage("commit1").call(); - assertFalse(db.getFS().canExecute(file1)); - - // Add second file - File file2 = writeTrashFile("file2.txt", "b"); - git.add().addFilepattern("file2.txt").call(); - git.commit().setMessage("commit2").call(); - assertFalse(db.getFS().canExecute(file2)); - - // Create branch from first commit - assertNotNull(git.checkout().setCreateBranch(true).setName("b1") - .setStartPoint(Constants.HEAD + "~1").call()); - - // Change content and file mode in working directory and index - file1 = writeTrashFile("file1.txt", "c"); - db.getFS().setExecute(file1, true); - git.add().addFilepattern("file1.txt").call(); - - // Switch back to 'master' - assertNotNull(git.checkout().setName(Constants.MASTER).call()); + ChangeRecorder recorder = new ChangeRecorder(); + ListenerHandle handle = null; + try (Git git = new Git(db)) { + handle = db.getListenerList() + .addWorkingTreeModifiedListener(recorder); + // Add first file + File file1 = writeTrashFile("file1.txt", "a"); + git.add().addFilepattern("file1.txt").call(); + git.commit().setMessage("commit1").call(); + assertFalse(db.getFS().canExecute(file1)); + + // Add second file + File file2 = writeTrashFile("file2.txt", "b"); + git.add().addFilepattern("file2.txt").call(); + git.commit().setMessage("commit2").call(); + assertFalse(db.getFS().canExecute(file2)); + recorder.assertNoEvent(); + + // Create branch from first commit + assertNotNull(git.checkout().setCreateBranch(true).setName("b1") + .setStartPoint(Constants.HEAD + "~1").call()); + recorder.assertEvent(ChangeRecorder.EMPTY, + new String[] { "file2.txt" }); + + // Change content and file mode in working directory and index + file1 = writeTrashFile("file1.txt", "c"); + db.getFS().setExecute(file1, true); + git.add().addFilepattern("file1.txt").call(); + + // Switch back to 'master' + assertNotNull(git.checkout().setName(Constants.MASTER).call()); + recorder.assertEvent(new String[] { "file2.txt" }, + ChangeRecorder.EMPTY); + } finally { + if (handle != null) { + handle.remove(); + } + } } @Test(expected = CheckoutConflictException.class) |