MetaDataUpdate: Do not close repository that was passed in

The repository to be updated by MetaDataUpdate can either be passed
in, or created based on other passed parameters.

If the repository is passed in, it should not be closed by the
MetaDataUpdate's close() method. This is because it is possible that
the repository was created in a try-with-resource block and will get
automatically closed. Closing it in MetaDataUpdate will then cause
the repository to be closed too many times, resulting in a corrupt use
count.

Update the static factory methods to prevent closing of the repository
that was passed in. Also update the Javadoc to explicitly mention that
the passed in repository must be closed by the caller.

Also rename 'db' member variable and parameters to 'repository' which
is more meaningful.

Bug: Issue 5404
Change-Id: I7ef68ecba31f1ca2528cf96c698c908c7303bdca
This commit is contained in:
David Pursehouse
2017-02-01 22:34:32 +09:00
parent 48d05ea980
commit 085a3089c5

View File

@@ -79,7 +79,10 @@ public class MetaDataUpdate implements AutoCloseable {
*/
public MetaDataUpdate create(Project.NameKey name, IdentifiedUser user,
BatchRefUpdate batch) throws RepositoryNotFoundException, IOException {
return create(name, mgr.openRepository(name), user, batch);
Repository repo = mgr.openRepository(name);
MetaDataUpdate md = create(name, repo, user, batch);
md.setCloseRepository(true);
return md;
}
/**
@@ -117,7 +120,8 @@ public class MetaDataUpdate implements AutoCloseable {
* </pre>
*
* @param name project name.
* @param repository GIT respository
* @param repository the repository to update; the caller is responsible for
* closing the repository.
* @param user user for the update.
* @param batch batch update to use; the caller is responsible for committing
* the update.
@@ -157,7 +161,9 @@ public class MetaDataUpdate implements AutoCloseable {
/** @see User#create(Project.NameKey, IdentifiedUser, BatchRefUpdate) */
public MetaDataUpdate create(Project.NameKey name, BatchRefUpdate batch)
throws RepositoryNotFoundException, IOException {
MetaDataUpdate md = factory.create(name, mgr.openRepository(name), batch);
Repository repo = mgr.openRepository(name);
MetaDataUpdate md = factory.create(name, repo, batch);
md.setCloseRepository(true);
md.getCommitBuilder().setAuthor(serverIdent);
md.getCommitBuilder().setCommitter(serverIdent);
return md;
@@ -166,32 +172,34 @@ public class MetaDataUpdate implements AutoCloseable {
interface InternalFactory {
MetaDataUpdate create(@Assisted Project.NameKey projectName,
@Assisted Repository db, @Assisted @Nullable BatchRefUpdate batch);
@Assisted Repository repository,
@Assisted @Nullable BatchRefUpdate batch);
}
private final GitReferenceUpdated gitRefUpdated;
private final Project.NameKey projectName;
private final Repository db;
private final Repository repository;
private final BatchRefUpdate batch;
private final CommitBuilder commit;
private boolean allowEmpty;
private boolean insertChangeId;
private boolean closeRepository;
private IdentifiedUser author;
@AssistedInject
public MetaDataUpdate(GitReferenceUpdated gitRefUpdated,
@Assisted Project.NameKey projectName, @Assisted Repository db,
@Assisted Project.NameKey projectName, @Assisted Repository repository,
@Assisted @Nullable BatchRefUpdate batch) {
this.gitRefUpdated = gitRefUpdated;
this.projectName = projectName;
this.db = db;
this.repository = repository;
this.batch = batch;
this.commit = new CommitBuilder();
}
public MetaDataUpdate(GitReferenceUpdated gitRefUpdated,
Project.NameKey projectName, Repository db) {
this(gitRefUpdated, projectName, db, null);
Project.NameKey projectName, Repository repository) {
this(gitRefUpdated, projectName, repository, null);
}
/** Set the commit message used when committing the update. */
@@ -214,6 +222,10 @@ public class MetaDataUpdate implements AutoCloseable {
this.insertChangeId = insertChangeId;
}
public void setCloseRepository(boolean closeRepository) {
this.closeRepository = closeRepository;
}
/** @return batch in which to run the update, or {@code null} for no batch. */
BatchRefUpdate getBatch() {
return batch;
@@ -222,7 +234,9 @@ public class MetaDataUpdate implements AutoCloseable {
/** Close the cached Repository handle. */
@Override
public void close() {
getRepository().close();
if (closeRepository) {
getRepository().close();
}
}
Project.NameKey getProjectName() {
@@ -230,7 +244,7 @@ public class MetaDataUpdate implements AutoCloseable {
}
public Repository getRepository() {
return db;
return repository;
}
boolean allowEmpty() {