diff options
author | Kevin Sawicki <kevin@github.com> | 2012-05-06 10:17:05 -0700 |
---|---|---|
committer | Kevin Sawicki <kevin@github.com> | 2012-05-28 14:01:37 -0700 |
commit | 531db82f38c307ee4ade9ac5c61229bc539f7d87 (patch) | |
tree | 7c6f0b7c63a0840fddd0fce6f411316e7aef921d | |
parent | dac66672df0535f61a13273524d46e1e0012ca69 (diff) | |
download | jgit-531db82f38c307ee4ade9ac5c61229bc539f7d87.tar.gz jgit-531db82f38c307ee4ade9ac5c61229bc539f7d87.zip |
Retain file length and mod time when doing a mixed reset
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
-rw-r--r-- | org.eclipse.jgit/src/org/eclipse/jgit/api/ResetCommand.java | 49 |
1 files changed, 43 insertions, 6 deletions
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 422056bd6d..0af684e7eb 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/ResetCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/ResetCommand.java @@ -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(); } } |