diff options
author | Christian Halstrick <christian.halstrick@sap.com> | 2016-06-17 16:41:14 +0200 |
---|---|---|
committer | Christian Halstrick <christian.halstrick@sap.com> | 2016-06-23 09:34:22 +0200 |
commit | 5fe44ed3ee025404dc34966ec996641f47f8490b (patch) | |
tree | 38cded9b222b7a4c832484d0a7ab3a123a811164 /org.eclipse.jgit.test/tst | |
parent | 2ec3accb3bcc0bd45dfb1333511c72489ab835cb (diff) | |
download | jgit-5fe44ed3ee025404dc34966ec996641f47f8490b.tar.gz jgit-5fe44ed3ee025404dc34966ec996641f47f8490b.zip |
Fix DirCacheCheckout to return CheckoutConflictException
Problem occurs when the checkout wants to create a file 'd/f' but
the workingtree contains a dirty file 'd'. In order to create d/f the
file 'd' would have to be deleted and since the file is dirty that
content would be lost. This should lead to a CheckoutConflictException
for d/f when failOnConflict was set to true.
This fix also changes jgit checkout semantics to be more like native
gits checkout semantics. If during a checkout jgit wants to delete a
folder but finds that the working tree contains a dirty file at this
path then JGit will now throw an exception instead of silently keeping
the dirty file. Like in this example:
git init
touch b
git add b
git commit -m addB
mkdir a
touch a/c
git add a/c
git commit -m addAC
rm -fr a
touch a
git checkout HEAD~
Change-Id: I9089123179e09dd565285d50b0caa308d290cccd
Signed-off-by: RĂ¼diger Herrmann <ruediger.herrmann@gmx.de>
Also-by: RĂ¼diger Herrmann <ruediger.herrmann@gmx.de>
Diffstat (limited to 'org.eclipse.jgit.test/tst')
-rw-r--r-- | org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/DirCacheCheckoutTest.java | 58 |
1 files changed, 58 insertions, 0 deletions
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 fbe7dd0417..bb553a444e 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 @@ -1614,6 +1614,64 @@ public class DirCacheCheckoutTest extends RepositoryTestCase { assertNotNull(git.checkout().setName(Constants.MASTER).call()); } + @Test(expected = CheckoutConflictException.class) + public void testFolderFileConflict() throws Exception { + RevCommit headCommit = commitFile("f/a", "initial content", "master"); + RevCommit checkoutCommit = commitFile("f/a", "side content", "side"); + FileUtils.delete(new File(db.getWorkTree(), "f"), FileUtils.RECURSIVE); + writeTrashFile("f", "file instead of folder"); + new DirCacheCheckout(db, headCommit.getTree(), db.lockDirCache(), + checkoutCommit.getTree()).checkout(); + } + + @Test + public void testMultipleContentConflicts() throws Exception { + commitFile("a", "initial content", "master"); + RevCommit headCommit = commitFile("b", "initial content", "master"); + commitFile("a", "side content", "side"); + RevCommit checkoutCommit = commitFile("b", "side content", "side"); + writeTrashFile("a", "changed content"); + writeTrashFile("b", "changed content"); + + try { + new DirCacheCheckout(db, headCommit.getTree(), db.lockDirCache(), + checkoutCommit.getTree()).checkout(); + fail(); + } catch (CheckoutConflictException expected) { + assertEquals(2, expected.getConflictingFiles().length); + assertTrue(Arrays.asList(expected.getConflictingFiles()) + .contains("a")); + assertTrue(Arrays.asList(expected.getConflictingFiles()) + .contains("b")); + assertEquals("changed content", read("a")); + assertEquals("changed content", read("b")); + } + } + + @Test + public void testFolderFileAndContentConflicts() throws Exception { + RevCommit headCommit = commitFile("f/a", "initial content", "master"); + commitFile("b", "side content", "side"); + RevCommit checkoutCommit = commitFile("f/a", "side content", "side"); + FileUtils.delete(new File(db.getWorkTree(), "f"), FileUtils.RECURSIVE); + writeTrashFile("f", "file instead of a folder"); + writeTrashFile("b", "changed content"); + + try { + new DirCacheCheckout(db, headCommit.getTree(), db.lockDirCache(), + checkoutCommit.getTree()).checkout(); + fail(); + } catch (CheckoutConflictException expected) { + assertEquals(2, expected.getConflictingFiles().length); + assertTrue(Arrays.asList(expected.getConflictingFiles()) + .contains("b")); + assertTrue(Arrays.asList(expected.getConflictingFiles()) + .contains("f")); + assertEquals("file instead of a folder", read("f")); + assertEquals("changed content", read("b")); + } + } + public void assertWorkDir(Map<String, String> i) throws CorruptObjectException, IOException { |