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;
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);
+ }
}
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;
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
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);
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);
}
}
- // 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
// 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
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());
}
}
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;
}