diff options
author | Kevin Sawicki <kevin@github.com> | 2012-03-13 17:01:42 -0700 |
---|---|---|
committer | Chris Aniszczyk <zx@twitter.com> | 2012-03-13 19:14:15 -0500 |
commit | 9be6526e9dbcfaca168dd66caac36a9316d44d88 (patch) | |
tree | 358e1d8a778116e11eac7ce75c383a832fbc00c9 /org.eclipse.jgit.test/tst/org/eclipse | |
parent | 6e13dfab4a2ea6a264abacd49ed36cbfa3dba128 (diff) | |
download | jgit-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.java | 110 |
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()); + } + } } |