Browse Source

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 <zx@twitter.com>
tags/v2.2.0.201212191850-r
Robin Stocker 11 years ago
parent
commit
3f1d56d6b7

+ 32
- 0
org.eclipse.jgit.test/tst/org/eclipse/jgit/api/ResetCommandTest.java View 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();

+ 12
- 25
org.eclipse.jgit/src/org/eclipse/jgit/api/ResetCommand.java View 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 {

Loading…
Cancel
Save