diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/AddCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/AddCommand.java index f7d4da4d5..29c520c17 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/AddCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/AddCommand.java @@ -43,8 +43,8 @@ */ package org.eclipse.jgit.api; -import java.io.File; import java.io.IOException; +import java.io.InputStream; import java.util.Collection; import java.util.LinkedList; @@ -54,7 +54,8 @@ import org.eclipse.jgit.dircache.DirCacheBuildIterator; import org.eclipse.jgit.dircache.DirCacheBuilder; import org.eclipse.jgit.dircache.DirCacheEntry; import org.eclipse.jgit.dircache.DirCacheIterator; -import org.eclipse.jgit.lib.ObjectWriter; +import org.eclipse.jgit.lib.Constants; +import org.eclipse.jgit.lib.ObjectInserter; import org.eclipse.jgit.lib.Repository; import org.eclipse.jgit.treewalk.FileTreeIterator; import org.eclipse.jgit.treewalk.TreeWalk; @@ -128,9 +129,9 @@ public class AddCommand extends GitCommand { if (filepatterns.contains(".")) addAll = true; + ObjectInserter inserter = repo.newObjectInserter(); try { dc = repo.lockDirCache(); - ObjectWriter ow = new ObjectWriter(repo); DirCacheIterator c; DirCacheBuilder builder = dc.builder(); @@ -149,7 +150,6 @@ public class AddCommand extends GitCommand { while (tw.next()) { String path = tw.getPathString(); - final File file = new File(repo.getWorkTree(), path); WorkingTreeIterator f = tw.getTree(1, WorkingTreeIterator.class); if (tw.getTree(0, DirCacheIterator.class) == null && f != null && f.isEntryIgnored()) { @@ -162,11 +162,19 @@ public class AddCommand extends GitCommand { else if (!(path.equals(lastAddedFile))) { if (!(update && tw.getTree(0, DirCacheIterator.class) == null)) { if (f != null) { // the file exists + long sz = f.getEntryLength(); DirCacheEntry entry = new DirCacheEntry(path); - entry.setLength((int)f.getEntryLength()); + entry.setLength(sz); entry.setLastModified(f.getEntryLastModified()); entry.setFileMode(f.getEntryFileMode()); - entry.setObjectId(ow.writeBlob(file)); + + InputStream in = f.openEntryStream(); + try { + entry.setObjectId(inserter.insert( + Constants.OBJ_BLOB, sz, in)); + } finally { + in.close(); + } builder.add(entry); lastAddedFile = path; @@ -177,12 +185,14 @@ public class AddCommand extends GitCommand { } } } + inserter.flush(); builder.commit(); setCallable(false); } catch (IOException e) { throw new JGitInternalException( JGitText.get().exceptionCaughtDuringExecutionOfAddCommand, e); } finally { + inserter.release(); if (dc != null) dc.unlock(); } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/WorkingTreeIterator.java b/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/WorkingTreeIterator.java index a1a60868a..5256e8aae 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/WorkingTreeIterator.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/WorkingTreeIterator.java @@ -384,6 +384,26 @@ public abstract class WorkingTreeIterator extends AbstractTreeIterator { return current().getLastModified(); } + /** + * Obtain an input stream to read the file content. + *

+ * Efficient implementations are not required. The caller will usually + * obtain the stream only once per entry, if at all. + *

+ * The input stream should not use buffering if the implementation can avoid + * it. The caller will buffer as necessary to perform efficient block IO + * operations. + *

+ * The caller will close the stream once complete. + * + * @return a stream to read from the file. + * @throws IOException + * the file could not be opened for reading. + */ + public InputStream openEntryStream() throws IOException { + return current().openInputStream(); + } + /** * Determine if the current entry path is ignored by an ignore rule. *