diff options
author | Thomas Wolf | 2017-05-11 20:17:54 +0000 |
---|---|---|
committer | Matthias Sohn | 2017-05-13 17:41:09 +0000 |
commit | f46237a20462b5451035c2a83e6177e2e7682cfd (patch) | |
tree | 028e3848f5e895930d20ae33b5a616e05f83300d /org.eclipse.egit.core.test | |
parent | fe77e2e9e8b22ac451410d3816ee339b995a155a (diff) | |
download | egit-f46237a.tar.gz egit-f46237a.tar.xz egit-f46237a.zip |
Fix synchronize with deleted resources
ResourceVariantTreeSubscriber.members() must return *all* resources
known to the subscriber, whether they exist in the "workspace" or not.
Otherwise resources that were deleted will be missed.
Git is a bit special in that we don't want to report .gitignored
resources, and untracked resources only if the user so wishes. Thus
our logic is a bit different and governed basically by what our 3-way
diff cache contains, but in any case we must include files
that only exist in the remote (i.e., in those caches).
Furthermore, isSupervised() must also work for IContainers, not just
for files. That was limited in commit 3fa9329 [1] to files to prevent
folders showing up with wrong markers. However, this kind of fix is
just plain wrong -- the new test could never work with that. But if
we re-consider folders as supervised, they'll show up as modified even
when they have no changes below. Our cache should contain IN_SYNC
entries for such folders. ThreeWayDifFEntry.scan() produces MODIFIED
entries, though.
Since I'm unsure about the interactions between scans with path
filters to partially update the EGit synchronization caches, I have
not touched that scan--it would be non-trivial to make it produce
IN_SYNC entries anyway, and then the cache update logic would probably
also have to be non-trivially adapted.
Instead I've chosen to perform a top-down check in GitSyncInfo and
return IN_SYNC for any folder that does not contain at least one file
that is itself not IN_SYNC.
[1] Ib25bf43721ef4cc87dba33aa01909e50a4cbef48; bug 324604
Bug: 516426
Change-Id: Ia12309f52e5140ff058b4fee17b9c7d48d435290
Signed-off-by: Thomas Wolf <thomas.wolf@paranor.ch>
Diffstat (limited to 'org.eclipse.egit.core.test')
-rw-r--r-- | org.eclipse.egit.core.test/src/org/eclipse/egit/core/synchronize/GitSubscriberResourceMappingContextTest.java | 100 |
1 files changed, 100 insertions, 0 deletions
diff --git a/org.eclipse.egit.core.test/src/org/eclipse/egit/core/synchronize/GitSubscriberResourceMappingContextTest.java b/org.eclipse.egit.core.test/src/org/eclipse/egit/core/synchronize/GitSubscriberResourceMappingContextTest.java index c8a5107d94..6e090f2b0d 100644 --- a/org.eclipse.egit.core.test/src/org/eclipse/egit/core/synchronize/GitSubscriberResourceMappingContextTest.java +++ b/org.eclipse.egit.core.test/src/org/eclipse/egit/core/synchronize/GitSubscriberResourceMappingContextTest.java @@ -7,6 +7,7 @@ *******************************************************************************/ package org.eclipse.egit.core.synchronize; +import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; @@ -14,6 +15,7 @@ import java.io.ByteArrayInputStream; import java.io.File; import java.io.UnsupportedEncodingException; +import org.eclipse.core.resources.IContainer; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IFolder; import org.eclipse.core.resources.IProject; @@ -292,6 +294,104 @@ public class GitSubscriberResourceMappingContextTest extends GitTestCase { assertFalse(context.hasLocalChange(file, new NullProgressMonitor())); } + @Test + public void hasDeletion() throws Exception { + File file1 = testRepo.createFile(iProject, "file1.sample"); + testRepo.appendContentAndCommit(iProject, file1, "initial content", + "first commit in master"); + + IFile iFile1 = testRepo.getIFile(iProject, file1); + + testRepo.createAndCheckoutBranch(MASTER, BRANCH); + iFile1.delete(true, new NullProgressMonitor()); + try (Git git = new Git(testRepo.getRepository())) { + git.add() + .addFilepattern(iProject.getName() + '/' + iFile1.getName()) + .setUpdate(true) + .call(); + } + testRepo.commit("Deleted file1.sample"); + + RemoteResourceMappingContext context = prepareContext(BRANCH, MASTER); + boolean hasFile1 = false; + for (IResource member : context.fetchMembers(iProject, + new NullProgressMonitor())) { + if (iFile1.getName().equals(member.getName())) { + hasFile1 = true; + break; + } + } + assertTrue(hasFile1); + assertFalse(context.hasRemoteChange(iFile1, new NullProgressMonitor())); + assertTrue(context.hasLocalChange(iFile1, new NullProgressMonitor())); + } + + @Test + public void hasNestedDeletion() throws Exception { + File file1 = testRepo.createFile(iProject, + "sub/subfolder/file1.sample"); + testRepo.appendContentAndCommit(iProject, file1, "initial content", + "first commit in master"); + + IFile iFile1 = testRepo.getIFile(iProject, file1); + + assertTrue(iFile1.exists()); + + IContainer subfolder = iFile1.getParent(); + + assertTrue(subfolder instanceof IFolder); + assertEquals("subfolder", subfolder.getName()); + + IContainer sub = subfolder.getParent(); + + assertTrue(sub instanceof IFolder); + assertEquals("sub", sub.getName()); + + testRepo.createAndCheckoutBranch(MASTER, BRANCH); + iFile1.delete(true, new NullProgressMonitor()); + subfolder.delete(true, new NullProgressMonitor()); + sub.delete(true, new NullProgressMonitor()); + try (Git git = new Git(testRepo.getRepository())) { + git.add() + .addFilepattern( + iProject.getName() + "/sub/subfolder/file1.sample") + .setUpdate(true).call(); + } + testRepo.commit("Deleted sub/subfolder/file1.sample"); + + assertFalse(iFile1.exists()); + assertFalse(subfolder.exists()); + assertFalse(sub.exists()); + + RemoteResourceMappingContext context = prepareContext(BRANCH, MASTER); + boolean hasFile1 = false; + for (IResource member : context.fetchMembers(iProject, + new NullProgressMonitor())) { + if (sub.getName().equals(member.getName())) { + for (IResource child : context.fetchMembers(sub, + new NullProgressMonitor())) { + if (subfolder.getName().equals(child.getName())) { + for (IResource grandchild : context.fetchMembers( + subfolder, new NullProgressMonitor())) { + if (iFile1.getName().equals(grandchild.getName())) { + hasFile1 = true; + break; + } + } + break; + } + } + break; + } + } + assertTrue(hasFile1); + assertFalse(context.hasRemoteChange(iFile1, new NullProgressMonitor())); + assertTrue(context.hasLocalChange(iFile1, new NullProgressMonitor())); + assertTrue( + context.hasLocalChange(subfolder, new NullProgressMonitor())); + assertTrue(context.hasLocalChange(sub, new NullProgressMonitor())); + } + private RevCommit setContentsAndCommit(IFile targetFile, String newContents, String commitMessage) throws Exception { |