From 3f1d56d6b7105eec88eea59730a5d78f668df179 Mon Sep 17 00:00:00 2001 From: Robin Stocker Date: Sun, 28 Oct 2012 15:35:21 +0100 Subject: [PATCH] ResetCommand: Correctly reset unmerged paths in resetIndexForPaths The previous implementation used a PathEdit, which does not reset the stage of the entry. Bug: 391860 Change-Id: If26d3a35abfee85424ad69de724f06a28b6e9efb Signed-off-by: Chris Aniszczyk --- .../eclipse/jgit/api/ResetCommandTest.java | 32 ++++++++++++++++ .../org/eclipse/jgit/api/ResetCommand.java | 37 ++++++------------- 2 files changed, 44 insertions(+), 25 deletions(-) diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/ResetCommandTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/ResetCommandTest.java index 8f2e54388b..3b0e7bd935 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/ResetCommandTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/ResetCommandTest.java @@ -58,9 +58,11 @@ import org.eclipse.jgit.api.ResetCommand.ResetType; import org.eclipse.jgit.api.errors.GitAPIException; import org.eclipse.jgit.api.errors.JGitInternalException; import org.eclipse.jgit.dircache.DirCache; +import org.eclipse.jgit.dircache.DirCacheBuilder; import org.eclipse.jgit.dircache.DirCacheEntry; import org.eclipse.jgit.errors.AmbiguousObjectException; import org.eclipse.jgit.lib.Constants; +import org.eclipse.jgit.lib.FileMode; import org.eclipse.jgit.lib.ObjectId; import org.eclipse.jgit.lib.RepositoryTestCase; import org.eclipse.jgit.revwalk.RevCommit; @@ -341,6 +343,36 @@ public class ResetCommandTest extends RepositoryTestCase { assertFalse(inIndex(untrackedFile.getName())); } + @Test + public void testPathsResetWithUnmerged() throws Exception { + setupRepository(); + + String file = "a.txt"; + writeTrashFile(file, "data"); + + git.add().addFilepattern(file).call(); + git.commit().setMessage("commit").call(); + + DirCache index = db.lockDirCache(); + DirCacheBuilder builder = index.builder(); + builder.add(createEntry(file, FileMode.REGULAR_FILE, 1, "")); + builder.add(createEntry(file, FileMode.REGULAR_FILE, 2, "")); + builder.add(createEntry(file, FileMode.REGULAR_FILE, 3, "")); + builder.add(createEntry("b.txt", FileMode.REGULAR_FILE)); + assertTrue(builder.commit()); + + assertEquals("[a.txt, mode:100644, stage:1]" + + "[a.txt, mode:100644, stage:2]" + + "[a.txt, mode:100644, stage:3]" + + "[b.txt, mode:100644]", + indexState(0)); + + git.reset().addPath(file).call(); + + assertEquals("[a.txt, mode:100644]" + "[b.txt, mode:100644]", + indexState(0)); + } + @Test public void testHardResetOnTag() throws Exception { setupRepository(); diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/ResetCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/ResetCommand.java index fc3d147c68..7f5eb0244c 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/ResetCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/ResetCommand.java @@ -51,6 +51,8 @@ import org.eclipse.jgit.api.errors.CheckoutConflictException; import org.eclipse.jgit.api.errors.GitAPIException; import org.eclipse.jgit.api.errors.JGitInternalException; import org.eclipse.jgit.dircache.DirCache; +import org.eclipse.jgit.dircache.DirCacheBuildIterator; +import org.eclipse.jgit.dircache.DirCacheBuilder; import org.eclipse.jgit.dircache.DirCacheCheckout; import org.eclipse.jgit.dircache.DirCacheEditor; import org.eclipse.jgit.dircache.DirCacheEditor.DeletePath; @@ -59,7 +61,6 @@ import org.eclipse.jgit.dircache.DirCacheEntry; import org.eclipse.jgit.dircache.DirCacheIterator; import org.eclipse.jgit.internal.JGitText; import org.eclipse.jgit.lib.Constants; -import org.eclipse.jgit.lib.FileMode; import org.eclipse.jgit.lib.ObjectId; import org.eclipse.jgit.lib.Ref; import org.eclipse.jgit.lib.RefUpdate; @@ -276,44 +277,30 @@ public class ResetCommand extends GitCommand { private void resetIndexForPaths(RevCommit commit) { DirCache dc = null; - final DirCacheEditor edit; try { dc = repo.lockDirCache(); - edit = dc.editor(); + DirCacheBuilder builder = dc.builder(); final TreeWalk tw = new TreeWalk(repo); - tw.addTree(new DirCacheIterator(dc)); + tw.addTree(new DirCacheBuildIterator(builder)); tw.addTree(commit.getTree()); tw.setFilter(PathFilterGroup.createFromStrings(filepaths)); tw.setRecursive(true); while (tw.next()) { - final String path = tw.getPathString(); - // DirCacheIterator dci = tw.getTree(0, DirCacheIterator.class); final CanonicalTreeParser tree = tw.getTree(1, CanonicalTreeParser.class); - if (tree == null) - // file is not in the commit, remove from index - edit.add(new DirCacheEditor.DeletePath(path)); - else { // revert index to commit - // it seams that there is concurrent access to tree - // variable, therefore we need to keep references to - // entryFileMode and entryObjectId in local - // variables - final FileMode entryFileMode = tree.getEntryFileMode(); - final ObjectId entryObjectId = tree.getEntryObjectId(); - edit.add(new DirCacheEditor.PathEdit(path) { - @Override - public void apply(DirCacheEntry ent) { - ent.setFileMode(entryFileMode); - ent.setObjectId(entryObjectId); - ent.setLastModified(0); - } - }); + // only keep file in index if it's in the commit + if (tree != null) { + // revert index to commit + DirCacheEntry entry = new DirCacheEntry(tw.getRawPath()); + entry.setFileMode(tree.getEntryFileMode()); + entry.setObjectId(tree.getEntryObjectId()); + builder.add(entry); } } - edit.commit(); + builder.commit(); } catch (IOException e) { throw new RuntimeException(e); } finally { -- 2.39.5