]> source.dussan.org Git - jgit.git/commitdiff
Retain file length and mod time when doing a mixed reset 38/6138/1
authorKevin Sawicki <kevin@github.com>
Sun, 6 May 2012 17:17:05 +0000 (10:17 -0700)
committerKevin Sawicki <kevin@github.com>
Mon, 28 May 2012 21:01:37 +0000 (14:01 -0700)
Previously the index was cleared and updated with a new tree.

Now the commit being reset to and the index are iterated over
in a tree walk and the current index mod time and file length
are copied over to the new dir cache entry being written if
the object ids are the same.

Change-Id: Iaf9e624efb0bf90f9e05fcb0587dde4dec50000c

org.eclipse.jgit/src/org/eclipse/jgit/api/ResetCommand.java

index 422056bd6d5c0d5c439392298fd14e2d47987262..0af684e7eb0328b127bc611d454b7fc474b55d16 100644 (file)
@@ -49,9 +49,10 @@ import java.util.LinkedList;
 
 import org.eclipse.jgit.api.errors.JGitInternalException;
 import org.eclipse.jgit.dircache.DirCache;
-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;
+import org.eclipse.jgit.dircache.DirCacheEditor.PathEdit;
 import org.eclipse.jgit.dircache.DirCacheEntry;
 import org.eclipse.jgit.dircache.DirCacheIterator;
 import org.eclipse.jgit.internal.JGitText;
@@ -64,6 +65,7 @@ import org.eclipse.jgit.lib.Repository;
 import org.eclipse.jgit.lib.RepositoryState;
 import org.eclipse.jgit.revwalk.RevCommit;
 import org.eclipse.jgit.revwalk.RevWalk;
+import org.eclipse.jgit.treewalk.AbstractTreeIterator;
 import org.eclipse.jgit.treewalk.CanonicalTreeParser;
 import org.eclipse.jgit.treewalk.TreeWalk;
 import org.eclipse.jgit.treewalk.filter.PathFilterGroup;
@@ -313,14 +315,49 @@ public class ResetCommand extends GitCommand<Ref> {
 
        private void resetIndex(RevCommit commit) throws IOException {
                DirCache dc = repo.lockDirCache();
+               TreeWalk walk = null;
                try {
-                       dc.clear();
-                       DirCacheBuilder dcb = dc.builder();
-                       dcb.addTree(new byte[0], 0, repo.newObjectReader(),
-                                       commit.getTree());
-                       dcb.commit();
+                       DirCacheEditor editor = dc.editor();
+
+                       walk = new TreeWalk(repo);
+                       walk.addTree(commit.getTree());
+                       walk.addTree(new DirCacheIterator(dc));
+                       walk.setRecursive(true);
+
+                       while (walk.next()) {
+                               AbstractTreeIterator cIter = walk.getTree(0,
+                                               AbstractTreeIterator.class);
+                               if (cIter == null) {
+                                       editor.add(new DeletePath(walk.getPathString()));
+                                       continue;
+                               }
+
+                               final DirCacheEntry entry = new DirCacheEntry(walk.getRawPath());
+                               entry.setFileMode(cIter.getEntryFileMode());
+                               entry.setObjectIdFromRaw(cIter.idBuffer(), cIter.idOffset());
+
+                               DirCacheIterator dcIter = walk.getTree(1,
+                                               DirCacheIterator.class);
+                               if (dcIter != null && dcIter.idEqual(cIter)) {
+                                       DirCacheEntry indexEntry = dcIter.getDirCacheEntry();
+                                       entry.setLastModified(indexEntry.getLastModified());
+                                       entry.setLength(indexEntry.getLength());
+                               }
+
+                               editor.add(new PathEdit(entry) {
+
+                                       @Override
+                                       public void apply(DirCacheEntry ent) {
+                                               ent.copyMetaData(entry);
+                                       }
+                               });
+                       }
+
+                       editor.commit();
                } finally {
                        dc.unlock();
+                       if (walk != null)
+                               walk.release();
                }
        }