diff options
author | Chris Aniszczyk <caniszczyk@gmail.com> | 2012-11-15 18:43:54 -0500 |
---|---|---|
committer | Gerrit Code Review @ Eclipse.org <gerrit@eclipse.org> | 2012-11-15 18:43:54 -0500 |
commit | e73c6873c7a770e8b102819c41fed0715d07dd62 (patch) | |
tree | ad6718ac914f670537cfd94a2aa4acea9be25390 | |
parent | 6a3b0668b7a9e1a79484aa6aa546bb6eb7c4304e (diff) | |
parent | 0f88d7b72ff09297954930cbe2a23cf8feff9382 (diff) | |
download | jgit-e73c6873c7a770e8b102819c41fed0715d07dd62.tar.gz jgit-e73c6873c7a770e8b102819c41fed0715d07dd62.zip |
Merge "CommitCommand: Ensure unmerged paths are added correctly with setOnly"
-rw-r--r-- | org.eclipse.jgit.test/tst/org/eclipse/jgit/api/CommitCommandTest.java | 54 | ||||
-rw-r--r-- | org.eclipse.jgit/src/org/eclipse/jgit/api/CommitCommand.java | 51 |
2 files changed, 82 insertions, 23 deletions
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/CommitCommandTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/CommitCommandTest.java index 3e73c7598e..45f312f38c 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/CommitCommandTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/CommitCommandTest.java @@ -55,6 +55,8 @@ import java.util.TimeZone; import org.eclipse.jgit.api.errors.WrongRepositoryStateException; import org.eclipse.jgit.diff.DiffEntry; import org.eclipse.jgit.dircache.DirCache; +import org.eclipse.jgit.dircache.DirCacheBuilder; +import org.eclipse.jgit.dircache.DirCacheEntry; import org.eclipse.jgit.lib.ConfigConstants; import org.eclipse.jgit.lib.Constants; import org.eclipse.jgit.lib.FileMode; @@ -471,4 +473,56 @@ public class CommitCommandTest extends RepositoryTestCase { assertEquals("New Author", amendedAuthor.getName()); assertEquals("newauthor@example.org", amendedAuthor.getEmailAddress()); } + + @Test + public void commitOnlyShouldCommitUnmergedPathAndNotAffectOthers() + throws Exception { + DirCache index = db.lockDirCache(); + DirCacheBuilder builder = index.builder(); + addUnmergedEntry("unmerged1", builder); + addUnmergedEntry("unmerged2", builder); + DirCacheEntry other = new DirCacheEntry("other"); + other.setFileMode(FileMode.REGULAR_FILE); + builder.add(other); + builder.commit(); + + writeTrashFile("unmerged1", "unmerged1 data"); + writeTrashFile("unmerged2", "unmerged2 data"); + writeTrashFile("other", "other data"); + + assertEquals("[other, mode:100644]" + + "[unmerged1, mode:100644, stage:1]" + + "[unmerged1, mode:100644, stage:2]" + + "[unmerged1, mode:100644, stage:3]" + + "[unmerged2, mode:100644, stage:1]" + + "[unmerged2, mode:100644, stage:2]" + + "[unmerged2, mode:100644, stage:3]", + indexState(0)); + + Git git = new Git(db); + RevCommit commit = git.commit().setOnly("unmerged1") + .setMessage("Only one file").call(); + + assertEquals("[other, mode:100644]" + "[unmerged1, mode:100644]" + + "[unmerged2, mode:100644, stage:1]" + + "[unmerged2, mode:100644, stage:2]" + + "[unmerged2, mode:100644, stage:3]", + indexState(0)); + + TreeWalk walk = TreeWalk.forPath(db, "unmerged1", commit.getTree()); + assertEquals(FileMode.REGULAR_FILE, walk.getFileMode(0)); + walk.release(); + } + + private static void addUnmergedEntry(String file, DirCacheBuilder builder) { + DirCacheEntry stage1 = new DirCacheEntry(file, DirCacheEntry.STAGE_1); + DirCacheEntry stage2 = new DirCacheEntry(file, DirCacheEntry.STAGE_2); + DirCacheEntry stage3 = new DirCacheEntry(file, DirCacheEntry.STAGE_3); + stage1.setFileMode(FileMode.REGULAR_FILE); + stage2.setFileMode(FileMode.REGULAR_FILE); + stage3.setFileMode(FileMode.REGULAR_FILE); + builder.add(stage1); + builder.add(stage2); + builder.add(stage3); + } } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/CommitCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/CommitCommand.java index ee92083175..eab2e8d4b8 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/CommitCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/CommitCommand.java @@ -58,10 +58,8 @@ import org.eclipse.jgit.api.errors.NoMessageException; import org.eclipse.jgit.api.errors.UnmergedPathsException; import org.eclipse.jgit.api.errors.WrongRepositoryStateException; import org.eclipse.jgit.dircache.DirCache; +import org.eclipse.jgit.dircache.DirCacheBuildIterator; import org.eclipse.jgit.dircache.DirCacheBuilder; -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.errors.UnmergedPathException; @@ -298,25 +296,26 @@ public class CommitCommand extends GitCommand<RevCommit> { throws IOException { ObjectInserter inserter = null; - // get DirCacheEditor to modify the index if required - DirCacheEditor dcEditor = index.editor(); + // get DirCacheBuilder for existing index + DirCacheBuilder existingBuilder = index.builder(); // get DirCacheBuilder for newly created in-core index to build a // temporary index for this commit DirCache inCoreIndex = DirCache.newInCore(); - DirCacheBuilder dcBuilder = inCoreIndex.builder(); + DirCacheBuilder tempBuilder = inCoreIndex.builder(); onlyProcessed = new boolean[only.size()]; boolean emptyCommit = true; TreeWalk treeWalk = new TreeWalk(repo); - int dcIdx = treeWalk.addTree(new DirCacheIterator(index)); + int dcIdx = treeWalk.addTree(new DirCacheBuildIterator(existingBuilder)); int fIdx = treeWalk.addTree(new FileTreeIterator(repo)); int hIdx = -1; if (headId != null) hIdx = treeWalk.addTree(new RevWalk(repo).parseTree(headId)); treeWalk.setRecursive(true); + String lastAddedFile = null; while (treeWalk.next()) { String path = treeWalk.getPathString(); // check if current entry's path matches a specified path @@ -326,11 +325,12 @@ public class CommitCommand extends GitCommand<RevCommit> { if (hIdx != -1) hTree = treeWalk.getTree(hIdx, CanonicalTreeParser.class); + DirCacheIterator dcTree = treeWalk.getTree(dcIdx, + DirCacheIterator.class); + if (pos >= 0) { // include entry in commit - DirCacheIterator dcTree = treeWalk.getTree(dcIdx, - DirCacheIterator.class); FileTreeIterator fTree = treeWalk.getTree(fIdx, FileTreeIterator.class); @@ -339,6 +339,13 @@ public class CommitCommand extends GitCommand<RevCommit> { if (!tracked) break; + // for an unmerged path, DirCacheBuildIterator will yield 3 + // entries, we only want to add one + if (path.equals(lastAddedFile)) + continue; + + lastAddedFile = path; + if (fTree != null) { // create a new DirCacheEntry with data retrieved from disk final DirCacheEntry dcEntry = new DirCacheEntry(path); @@ -371,15 +378,10 @@ public class CommitCommand extends GitCommand<RevCommit> { } } - // update index - dcEditor.add(new PathEdit(path) { - @Override - public void apply(DirCacheEntry ent) { - ent.copyMetaData(dcEntry); - } - }); + // add to existing index + existingBuilder.add(dcEntry); // add to temporary in-core index - dcBuilder.add(dcEntry); + tempBuilder.add(dcEntry); if (emptyCommit && (hTree == null || !hTree.idEqual(fTree) || hTree @@ -388,9 +390,8 @@ public class CommitCommand extends GitCommand<RevCommit> { // this is a change emptyCommit = false; } else { - // if no file exists on disk, remove entry from index and - // don't add it to temporary in-core index - dcEditor.add(new DeletePath(path)); + // if no file exists on disk, neither add it to + // index nor to temporary in-core index if (emptyCommit && hTree != null) // this is a change @@ -408,8 +409,12 @@ public class CommitCommand extends GitCommand<RevCommit> { dcEntry.setFileMode(hTree.getEntryFileMode()); // add to temporary in-core index - dcBuilder.add(dcEntry); + tempBuilder.add(dcEntry); } + + // preserve existing entry in index + if (dcTree != null) + existingBuilder.add(dcTree.getDirCacheEntry()); } } @@ -425,9 +430,9 @@ public class CommitCommand extends GitCommand<RevCommit> { throw new JGitInternalException(JGitText.get().emptyCommit); // update index - dcEditor.commit(); + existingBuilder.commit(); // finish temporary in-core index used for this commit - dcBuilder.finish(); + tempBuilder.finish(); return inCoreIndex; } |