aboutsummaryrefslogtreecommitdiffstats
path: root/org.eclipse.jgit.test/tst/org/eclipse
diff options
context:
space:
mode:
authorKevin Sawicki <kevin@github.com>2012-03-13 17:01:42 -0700
committerChris Aniszczyk <zx@twitter.com>2012-03-13 19:14:15 -0500
commit9be6526e9dbcfaca168dd66caac36a9316d44d88 (patch)
tree358e1d8a778116e11eac7ce75c383a832fbc00c9 /org.eclipse.jgit.test/tst/org/eclipse
parent6e13dfab4a2ea6a264abacd49ed36cbfa3dba128 (diff)
downloadjgit-9be6526e9dbcfaca168dd66caac36a9316d44d88.tar.gz
jgit-9be6526e9dbcfaca168dd66caac36a9316d44d88.zip
Only unstash files changed when originally stashed
Previously a DirCacheCheckout was done using a merge tree reflecting the state of the repository when the stash was originally done. This was wrong since unstashing after making subsequent commits would undo changes already committed by checking out entries from an outdated tree. The new approach is to scan for conflicts initially using a 6-way tree walk that contains the trees for the stashed HEAD, stashed index, stashed working directory, current HEAD, current index, and current working directory. Then perform a subsequent scan of the stashed HEAD, index, and working directory trees and apply all the stashed differences to the current index and working directory. Bug: 372882 Change-Id: Ica65f162132c00a16964e838de66fc8b5cd0b0aa Signed-off-by: Chris Aniszczyk <zx@twitter.com>
Diffstat (limited to 'org.eclipse.jgit.test/tst/org/eclipse')
-rw-r--r--org.eclipse.jgit.test/tst/org/eclipse/jgit/api/StashApplyCommandTest.java110
1 files changed, 110 insertions, 0 deletions
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 97d0efe109..bc11b7a703 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
@@ -46,10 +46,18 @@ import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
import java.io.File;
+import java.text.MessageFormat;
+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.errors.CheckoutConflictException;
+import org.eclipse.jgit.internal.JGitText;
import org.eclipse.jgit.lib.ObjectId;
+import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.lib.RepositoryTestCase;
import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.util.FileUtils;
@@ -343,4 +351,106 @@ public class StashApplyCommandTest extends RepositoryTestCase {
assertEquals(1, status.getAdded().size());
assertTrue(status.getAdded().contains(addedPath));
}
+
+ @Test
+ public void workingDirectoryContentConflict() throws Exception {
+ writeTrashFile(PATH, "content2");
+
+ RevCommit stashed = git.stashCreate().call();
+ assertNotNull(stashed);
+ assertEquals("content", read(committedFile));
+ assertTrue(git.status().call().isClean());
+
+ writeTrashFile(PATH, "content3");
+
+ try {
+ git.stashApply().call();
+ fail("Exception not thrown");
+ } catch (JGitInternalException e) {
+ assertTrue(e.getCause() instanceof CheckoutConflictException);
+ }
+ }
+
+ @Test
+ public void indexContentConflict() throws Exception {
+ writeTrashFile(PATH, "content2");
+
+ RevCommit stashed = git.stashCreate().call();
+ assertNotNull(stashed);
+ assertEquals("content", read(committedFile));
+ assertTrue(git.status().call().isClean());
+
+ writeTrashFile(PATH, "content3");
+ git.add().addFilepattern(PATH).call();
+ writeTrashFile(PATH, "content2");
+
+ try {
+ git.stashApply().call();
+ fail("Exception not thrown");
+ } catch (JGitInternalException e) {
+ assertTrue(e.getCause() instanceof CheckoutConflictException);
+ }
+ }
+
+ @Test
+ public void workingDirectoryEditPreCommit() throws Exception {
+ writeTrashFile(PATH, "content2");
+
+ RevCommit stashed = git.stashCreate().call();
+ assertNotNull(stashed);
+ assertEquals("content", read(committedFile));
+ assertTrue(git.status().call().isClean());
+
+ String path2 = "file2.txt";
+ writeTrashFile(path2, "content3");
+ git.add().addFilepattern(path2).call();
+ assertNotNull(git.commit().setMessage("adding file").call());
+
+ ObjectId unstashed = git.stashApply().call();
+ assertEquals(stashed, unstashed);
+
+ Status status = git.status().call();
+ assertTrue(status.getAdded().isEmpty());
+ assertTrue(status.getChanged().isEmpty());
+ assertTrue(status.getConflicting().isEmpty());
+ assertTrue(status.getMissing().isEmpty());
+ assertTrue(status.getRemoved().isEmpty());
+ assertTrue(status.getUntracked().isEmpty());
+
+ assertEquals(1, status.getModified().size());
+ assertTrue(status.getModified().contains(PATH));
+ }
+
+ @Test
+ public void unstashNonStashCommit() throws Exception {
+ try {
+ git.stashApply().setStashRef(head.name()).call();
+ fail("Exception not thrown");
+ } catch (JGitInternalException e) {
+ assertEquals(MessageFormat.format(
+ JGitText.get().stashCommitMissingTwoParents, head.name()),
+ e.getMessage());
+ }
+ }
+
+ @Test
+ public void unstashNoHead() throws Exception {
+ Repository repo = createWorkRepository();
+ try {
+ Git.wrap(repo).stashApply().call();
+ fail("Exception not thrown");
+ } catch (NoHeadException e) {
+ assertNotNull(e.getMessage());
+ }
+ }
+
+ @Test
+ public void noStashedCommits() throws Exception {
+ try {
+ git.stashApply().call();
+ fail("Exception not thrown");
+ } catch (InvalidRefNameException e) {
+ assertNotNull(e.getMessage());
+ }
+ }
}