]> source.dussan.org Git - jgit.git/commitdiff
ResetCommand: Correctly reset unmerged paths in resetIndexForPaths 87/8387/2
authorRobin Stocker <robin@nibor.org>
Sun, 28 Oct 2012 14:35:21 +0000 (15:35 +0100)
committerChris Aniszczyk <zx@twitter.com>
Thu, 1 Nov 2012 17:33:50 +0000 (10:33 -0700)
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 <zx@twitter.com>
org.eclipse.jgit.test/tst/org/eclipse/jgit/api/ResetCommandTest.java
org.eclipse.jgit/src/org/eclipse/jgit/api/ResetCommand.java

index 8f2e54388bd2235a4cc599724ea6cca87d4830ff..3b0e7bd935e42e32beaa011b935287a5b8fa9285 100644 (file)
@@ -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();
index fc3d147c68dd4925114018f8b840de77167a3d74..7f5eb0244c7d0ac1450fd44aa909747a2ab204d3 100644 (file)
@@ -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<Ref> {
 
        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 {