PushCertificateStore: Add method to save in batch

Change-Id: I8bfaee1a52d368ffe2cd7e8af1754a5261569078
This commit is contained in:
Dave Borowitz 2015-07-10 17:12:54 -07:00
parent b4ecb88367
commit f946ed1d97
2 changed files with 80 additions and 14 deletions

View File

@ -60,7 +60,9 @@
import org.eclipse.jgit.internal.storage.dfs.DfsRepositoryDescription;
import org.eclipse.jgit.internal.storage.dfs.InMemoryRepository;
import org.eclipse.jgit.lib.BatchRefUpdate;
import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.lib.NullProgressMonitor;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.PersonIdent;
import org.eclipse.jgit.revwalk.RevCommit;
@ -271,6 +273,26 @@ public void lockFailure() throws Exception {
assertCerts(store2, "refs/heads/branch", addBranch);
}
@Test
public void saveInBatch() throws Exception {
BatchRefUpdate batch = repo.getRefDatabase().newBatchUpdate();
PushCertificate addMaster = newCert(
command(zeroId(), ID1, "refs/heads/master"));
store.put(addMaster, newIdent());
store.save(batch);
List<ReceiveCommand> commands = batch.getCommands();
assertEquals(1, commands.size());
ReceiveCommand cmd = commands.get(0);
try (RevWalk rw = new RevWalk(repo)) {
assertEquals("refs/meta/push-certs", cmd.getRefName());
assertEquals(ReceiveCommand.Result.NOT_ATTEMPTED, cmd.getResult());
batch.execute(rw, NullProgressMonitor.INSTANCE);
assertEquals(ReceiveCommand.Result.OK, cmd.getResult());
}
}
private PersonIdent newIdent() {
return new PersonIdent(
"A U. Thor", "author@example.com", ts.getAndIncrement(), 0);

View File

@ -67,6 +67,7 @@
import org.eclipse.jgit.dircache.DirCacheEditor.PathEdit;
import org.eclipse.jgit.dircache.DirCacheEntry;
import org.eclipse.jgit.internal.JGitText;
import org.eclipse.jgit.lib.BatchRefUpdate;
import org.eclipse.jgit.lib.CommitBuilder;
import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.lib.FileMode;
@ -326,9 +327,64 @@ public void put(PushCertificate cert, PersonIdent ident) {
* repository.
*/
public RefUpdate.Result save() throws IOException {
if (pending.isEmpty()) {
ObjectId newId = write();
if (newId == null) {
return RefUpdate.Result.NO_CHANGE;
}
try (ObjectInserter inserter = db.newObjectInserter()) {
RefUpdate.Result result = updateRef(newId);
switch (result) {
case FAST_FORWARD:
case NEW:
case NO_CHANGE:
pending.clear();
break;
default:
break;
}
return result;
} finally {
close();
}
}
/**
* Save pending certificates to the store in an existing batch ref update.
* <p>
* One commit is created per certificate added with {@link
* #put(PushCertificate, PersonIdent)}, in order of identity timestamps, all
* commits are flushed, and a single command is added to the batch.
* <p>
* The pending list is <em>not</em> cleared. If the ref update succeeds, the
* caller is responsible for calling {@link #clear()}.
*
* @param batch
* update to save to.
* @throws IOException
* if there was an error reading from or writing to the
* repository.
*/
public void save(BatchRefUpdate batch) throws IOException {
ObjectId newId = write();
if (newId == null) {
return;
}
batch.addCommand(new ReceiveCommand(
commit != null ? commit : ObjectId.zeroId(), newId, REF_NAME));
}
/**
* Clear pending certificates added with {@link #put(PushCertificate,
* PersonIdent)}.
*/
public void clear() {
pending.clear();
}
private ObjectId write() throws IOException {
if (pending.isEmpty()) {
return null;
}
if (reader == null) {
load();
}
@ -341,19 +397,7 @@ public RefUpdate.Result save() throws IOException {
curr = saveCert(inserter, dc, pc, curr);
}
inserter.flush();
RefUpdate.Result result = updateRef(curr);
switch (result) {
case FAST_FORWARD:
case NEW:
case NO_CHANGE:
pending.clear();
break;
default:
break;
}
return result;
} finally {
close();
return curr;
}
}