Release ArchiveCommand's ObjectReader in call()
Make call() release all private resources so instead of using a pattern like ArchiveCommand cmd = git.archive(); try { cmd.setTree(tree) . ... .call(); } finally { cmd.release(); } callers can just use git.archive().setTree(tree)....call() directly. This involves pushing more work out of parameter setters and into call() so the ObjectReader is not allocated and potentially leaked before then. Change-Id: I699f703c6302696e1cc276d7ab8ee597d82f2c5d
This commit is contained in:
parent
56276d053f
commit
f99fa9d23e
|
@ -72,15 +72,14 @@ protected void run() throws Exception {
|
|||
if (tree == null)
|
||||
throw die(CLIText.get().treeIsRequired);
|
||||
|
||||
final ArchiveCommand cmd = new Git(db).archive();
|
||||
try {
|
||||
cmd.setTree(tree)
|
||||
new Git(db).archive()
|
||||
.setTree(tree)
|
||||
.setFormat(format)
|
||||
.setOutputStream(outs).call();
|
||||
.setOutputStream(outs)
|
||||
.call();
|
||||
} catch (GitAPIException e) {
|
||||
throw die(e.getMessage());
|
||||
} finally {
|
||||
cmd.release();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -72,12 +72,12 @@
|
|||
*
|
||||
* <pre>
|
||||
* ArchiveCommand.registerFormat("tar", new TarFormat());
|
||||
* cmd = git.archive();
|
||||
* try {
|
||||
* cmd.setTree(db.resolve("HEAD"))
|
||||
* .setOutputStream(out).call();
|
||||
* git.archive()
|
||||
* .setTree(db.resolve("HEAD"))
|
||||
* .setOutputStream(out)
|
||||
* .call();
|
||||
* } finally {
|
||||
* cmd.release();
|
||||
* ArchiveCommand.unregisterFormat("tar");
|
||||
* }
|
||||
* </pre>
|
||||
|
@ -87,11 +87,12 @@
|
|||
* <pre>
|
||||
* ArchiveCommand.registerFormat("zip", new ZipFormat());
|
||||
* try {
|
||||
* cmd.setTree(db.resolve("master"))
|
||||
* git.archive().
|
||||
* .setTree(db.resolve("master"))
|
||||
* .setFormat("zip")
|
||||
* .setOutputStream(out).call();
|
||||
* .setOutputStream(out)
|
||||
* .call();
|
||||
* } finally {
|
||||
* cmd.release();
|
||||
* ArchiveCommand.unregisterFormat("zip");
|
||||
* }
|
||||
* </pre>
|
||||
|
@ -197,7 +198,7 @@ private static Format<?> lookupFormat(String formatName) throws UnsupportedForma
|
|||
}
|
||||
|
||||
private OutputStream out;
|
||||
private TreeWalk walk;
|
||||
private ObjectId tree;
|
||||
private String format = "tar";
|
||||
|
||||
/**
|
||||
|
@ -205,27 +206,20 @@ private static Format<?> lookupFormat(String formatName) throws UnsupportedForma
|
|||
*/
|
||||
public ArchiveCommand(Repository repo) {
|
||||
super(repo);
|
||||
walk = new TreeWalk(repo);
|
||||
}
|
||||
|
||||
/**
|
||||
* Release any resources used by the internal ObjectReader.
|
||||
* <p>
|
||||
* This does not close the output stream set with setOutputStream, which
|
||||
* belongs to the caller.
|
||||
*/
|
||||
public void release() {
|
||||
walk.release();
|
||||
setCallable(false);
|
||||
}
|
||||
|
||||
private <T extends Closeable>
|
||||
OutputStream writeArchive(Format<T> fmt) throws GitAPIException {
|
||||
final MutableObjectId idBuf = new MutableObjectId();
|
||||
final TreeWalk walk = new TreeWalk(repo);
|
||||
try {
|
||||
final T outa = fmt.createArchiveOutputStream(out);
|
||||
try {
|
||||
final MutableObjectId idBuf = new MutableObjectId();
|
||||
final ObjectReader reader = walk.getObjectReader();
|
||||
final RevWalk rw = new RevWalk(walk.getObjectReader());
|
||||
|
||||
try {
|
||||
try {
|
||||
walk.reset(rw.parseTree(tree));
|
||||
walk.setRecursive(true);
|
||||
while (walk.next()) {
|
||||
final String name = walk.getPathString();
|
||||
|
@ -242,13 +236,14 @@ OutputStream writeArchive(Format<T> fmt) throws GitAPIException {
|
|||
} finally {
|
||||
outa.close();
|
||||
}
|
||||
return out;
|
||||
} catch (IOException e) {
|
||||
// TODO(jrn): Throw finer-grained errors.
|
||||
throw new JGitInternalException(
|
||||
JGitText.get().exceptionCaughtDuringExecutionOfArchiveCommand, e);
|
||||
} finally {
|
||||
walk.release();
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -256,6 +251,8 @@ OutputStream writeArchive(Format<T> fmt) throws GitAPIException {
|
|||
*/
|
||||
@Override
|
||||
public OutputStream call() throws GitAPIException {
|
||||
checkCallable();
|
||||
|
||||
final Format<?> fmt = lookupFormat(format);
|
||||
return writeArchive(fmt);
|
||||
}
|
||||
|
@ -264,11 +261,13 @@ public OutputStream call() throws GitAPIException {
|
|||
* @param tree
|
||||
* the tag, commit, or tree object to produce an archive for
|
||||
* @return this
|
||||
* @throws IOException
|
||||
*/
|
||||
public ArchiveCommand setTree(ObjectId tree) throws IOException {
|
||||
final RevWalk rw = new RevWalk(walk.getObjectReader());
|
||||
walk.reset(rw.parseTree(tree));
|
||||
public ArchiveCommand setTree(ObjectId tree) {
|
||||
if (tree == null)
|
||||
throw new IllegalArgumentException();
|
||||
|
||||
this.tree = tree;
|
||||
setCallable(true);
|
||||
return this;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue