Reuse ObjectReader for all objects touched during checkout
Bug: 349361 Change-Id: I61ffcb7694eb8b99ebaf4d0d0acd63e0ee91bcb3 Signed-off-by: Matthias Sohn <matthias.sohn@sap.com> Signed-off-by: Christian Halstrick <christian.halstrick@sap.com>
This commit is contained in:
parent
6d293c7b06
commit
1067f82f56
|
@ -66,6 +66,7 @@
|
|||
import org.eclipse.jgit.lib.AnyObjectId;
|
||||
import org.eclipse.jgit.lib.Constants;
|
||||
import org.eclipse.jgit.lib.ObjectId;
|
||||
import org.eclipse.jgit.lib.ObjectReader;
|
||||
import org.eclipse.jgit.lib.Ref;
|
||||
import org.eclipse.jgit.lib.RefUpdate;
|
||||
import org.eclipse.jgit.lib.RefUpdate.Result;
|
||||
|
@ -266,9 +267,14 @@ public void apply(DirCacheEntry ent) {
|
|||
}
|
||||
|
||||
File workTree = repo.getWorkTree();
|
||||
for (String file : files)
|
||||
DirCacheCheckout.checkoutEntry(repo, new File(workTree, file),
|
||||
dc.getEntry(file));
|
||||
ObjectReader r = repo.getObjectDatabase().newReader();
|
||||
try {
|
||||
for (String file : files)
|
||||
DirCacheCheckout.checkoutEntry(repo, new File(workTree,
|
||||
file), dc.getEntry(file), r);
|
||||
} finally {
|
||||
r.release();
|
||||
}
|
||||
} finally {
|
||||
dc.unlock();
|
||||
revWalk.release();
|
||||
|
|
|
@ -60,6 +60,7 @@
|
|||
import org.eclipse.jgit.lib.FileMode;
|
||||
import org.eclipse.jgit.lib.ObjectId;
|
||||
import org.eclipse.jgit.lib.ObjectLoader;
|
||||
import org.eclipse.jgit.lib.ObjectReader;
|
||||
import org.eclipse.jgit.lib.Repository;
|
||||
import org.eclipse.jgit.treewalk.AbstractTreeIterator;
|
||||
import org.eclipse.jgit.treewalk.CanonicalTreeParser;
|
||||
|
@ -386,64 +387,68 @@ private boolean doCheckout() throws CorruptObjectException, IOException,
|
|||
MissingObjectException, IncorrectObjectTypeException,
|
||||
CheckoutConflictException, IndexWriteException {
|
||||
toBeDeleted.clear();
|
||||
if (headCommitTree != null)
|
||||
preScanTwoTrees();
|
||||
else
|
||||
prescanOneTree();
|
||||
|
||||
if (!conflicts.isEmpty()) {
|
||||
if (failOnConflict) {
|
||||
dc.unlock();
|
||||
throw new CheckoutConflictException(conflicts.toArray(new String[conflicts.size()]));
|
||||
} else
|
||||
cleanUpConflicts();
|
||||
}
|
||||
ObjectReader objectReader = repo.getObjectDatabase().newReader();
|
||||
try {
|
||||
if (headCommitTree != null)
|
||||
preScanTwoTrees();
|
||||
else
|
||||
prescanOneTree();
|
||||
|
||||
// update our index
|
||||
builder.finish();
|
||||
if (!conflicts.isEmpty()) {
|
||||
if (failOnConflict) {
|
||||
dc.unlock();
|
||||
throw new CheckoutConflictException(conflicts.toArray(new String[conflicts.size()]));
|
||||
} else
|
||||
cleanUpConflicts();
|
||||
}
|
||||
|
||||
File file=null;
|
||||
String last = "";
|
||||
// when deleting files process them in the opposite order as they have
|
||||
// been reported. This ensures the files are deleted before we delete
|
||||
// their parent folders
|
||||
for (int i = removed.size() - 1; i >= 0; i--) {
|
||||
String r = removed.get(i);
|
||||
file = new File(repo.getWorkTree(), r);
|
||||
if (!file.delete() && file.exists())
|
||||
// update our index
|
||||
builder.finish();
|
||||
|
||||
File file = null;
|
||||
String last = "";
|
||||
// when deleting files process them in the opposite order as they have
|
||||
// been reported. This ensures the files are deleted before we delete
|
||||
// their parent folders
|
||||
for (int i = removed.size() - 1; i >= 0; i--) {
|
||||
String r = removed.get(i);
|
||||
file = new File(repo.getWorkTree(), r);
|
||||
if (!file.delete() && file.exists())
|
||||
toBeDeleted.add(r);
|
||||
else {
|
||||
if (!isSamePrefix(r, last))
|
||||
removeEmptyParents(new File(repo.getWorkTree(), last));
|
||||
last = r;
|
||||
else {
|
||||
if (!isSamePrefix(r, last))
|
||||
removeEmptyParents(new File(repo.getWorkTree(), last));
|
||||
last = r;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (file != null)
|
||||
removeEmptyParents(file);
|
||||
if (file != null)
|
||||
removeEmptyParents(file);
|
||||
|
||||
for (String path : updated.keySet()) {
|
||||
// ... create/overwrite this file ...
|
||||
file = new File(repo.getWorkTree(), path);
|
||||
if (!file.getParentFile().mkdirs()) {
|
||||
// ignore
|
||||
for (String path : updated.keySet()) {
|
||||
// ... create/overwrite this file ...
|
||||
file = new File(repo.getWorkTree(), path);
|
||||
if (!file.getParentFile().mkdirs()) {
|
||||
// ignore
|
||||
}
|
||||
|
||||
DirCacheEntry entry = dc.getEntry(path);
|
||||
|
||||
// submodules are handled with separate operations
|
||||
if (FileMode.GITLINK.equals(entry.getRawMode()))
|
||||
continue;
|
||||
|
||||
checkoutEntry(repo, file, entry, objectReader);
|
||||
}
|
||||
|
||||
DirCacheEntry entry = dc.getEntry(path);
|
||||
|
||||
// submodules are handled with separate operations
|
||||
if (FileMode.GITLINK.equals(entry.getRawMode()))
|
||||
continue;
|
||||
|
||||
checkoutEntry(repo, file, entry);
|
||||
// commit the index builder - a new index is persisted
|
||||
if (!builder.commit()) {
|
||||
dc.unlock();
|
||||
throw new IndexWriteException();
|
||||
}
|
||||
} finally {
|
||||
objectReader.release();
|
||||
}
|
||||
|
||||
|
||||
// commit the index builder - a new index is persisted
|
||||
if (!builder.commit()) {
|
||||
dc.unlock();
|
||||
throw new IndexWriteException();
|
||||
}
|
||||
|
||||
return toBeDeleted.size() == 0;
|
||||
}
|
||||
|
||||
|
@ -848,12 +853,19 @@ private boolean isModified(String path) throws CorruptObjectException, IOExcepti
|
|||
* Updates the file in the working tree with content and mode from an entry
|
||||
* in the index. The new content is first written to a new temporary file in
|
||||
* the same directory as the real file. Then that new file is renamed to the
|
||||
* final filename.
|
||||
* final filename. Use this method only for checkout of a single entry.
|
||||
* Otherwise use
|
||||
* {@code checkoutEntry(Repository, File f, DirCacheEntry, ObjectReader)}
|
||||
* instead which allows to reuse one {@code ObjectReader} for multiple
|
||||
* entries.
|
||||
*
|
||||
* <p>
|
||||
* TODO: this method works directly on File IO, we may need another
|
||||
* abstraction (like WorkingTreeIterator). This way we could tell e.g.
|
||||
* Eclipse that Files in the workspace got changed
|
||||
* @param repo
|
||||
* </p>
|
||||
*
|
||||
* @param repository
|
||||
* @param f
|
||||
* the file to be modified. The parent directory for this file
|
||||
* has to exist already
|
||||
|
@ -861,9 +873,41 @@ private boolean isModified(String path) throws CorruptObjectException, IOExcepti
|
|||
* the entry containing new mode and content
|
||||
* @throws IOException
|
||||
*/
|
||||
public static void checkoutEntry(final Repository repo, File f,
|
||||
public static void checkoutEntry(final Repository repository, File f,
|
||||
DirCacheEntry entry) throws IOException {
|
||||
ObjectLoader ol = repo.open(entry.getObjectId());
|
||||
ObjectReader or = repository.newObjectReader();
|
||||
try {
|
||||
checkoutEntry(repository, f, entry, repository.newObjectReader());
|
||||
} finally {
|
||||
or.release();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the file in the working tree with content and mode from an entry
|
||||
* in the index. The new content is first written to a new temporary file in
|
||||
* the same directory as the real file. Then that new file is renamed to the
|
||||
* final filename.
|
||||
*
|
||||
* <p>
|
||||
* TODO: this method works directly on File IO, we may need another
|
||||
* abstraction (like WorkingTreeIterator). This way we could tell e.g.
|
||||
* Eclipse that Files in the workspace got changed
|
||||
* </p>
|
||||
*
|
||||
* @param repo
|
||||
* @param f
|
||||
* the file to be modified. The parent directory for this file
|
||||
* has to exist already
|
||||
* @param entry
|
||||
* the entry containing new mode and content
|
||||
* @param or
|
||||
* object reader to use for checkout
|
||||
* @throws IOException
|
||||
*/
|
||||
public static void checkoutEntry(final Repository repo, File f,
|
||||
DirCacheEntry entry, ObjectReader or) throws IOException {
|
||||
ObjectLoader ol = or.open(entry.getObjectId());
|
||||
File parentDir = f.getParentFile();
|
||||
File tmpFile = File.createTempFile("._" + f.getName(), null, parentDir);
|
||||
FileOutputStream channel = new FileOutputStream(tmpFile);
|
||||
|
|
|
@ -238,19 +238,23 @@ protected boolean mergeImpl() throws IOException {
|
|||
}
|
||||
|
||||
private void checkout() throws NoWorkTreeException, IOException {
|
||||
for (Map.Entry<String, DirCacheEntry> entry : toBeCheckedOut.entrySet()) {
|
||||
File f = new File(db.getWorkTree(), entry.getKey());
|
||||
if (entry.getValue() != null) {
|
||||
createDir(f.getParentFile());
|
||||
DirCacheCheckout.checkoutEntry(db,
|
||||
f,
|
||||
entry.getValue());
|
||||
} else {
|
||||
if (!f.delete())
|
||||
failingPaths.put(entry.getKey(),
|
||||
MergeFailureReason.COULD_NOT_DELETE);
|
||||
ObjectReader r = db.getObjectDatabase().newReader();
|
||||
try {
|
||||
for (Map.Entry<String, DirCacheEntry> entry : toBeCheckedOut
|
||||
.entrySet()) {
|
||||
File f = new File(db.getWorkTree(), entry.getKey());
|
||||
if (entry.getValue() != null) {
|
||||
createDir(f.getParentFile());
|
||||
DirCacheCheckout.checkoutEntry(db, f, entry.getValue(), r);
|
||||
} else {
|
||||
if (!f.delete())
|
||||
failingPaths.put(entry.getKey(),
|
||||
MergeFailureReason.COULD_NOT_DELETE);
|
||||
}
|
||||
modifiedFiles.add(entry.getKey());
|
||||
}
|
||||
modifiedFiles.add(entry.getKey());
|
||||
} finally {
|
||||
r.release();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue