Browse Source

PushCertificateStore: Add method to save in batch

Change-Id: I8bfaee1a52d368ffe2cd7e8af1754a5261569078
stable-4.1
Dave Borowitz 9 years ago
parent
commit
f946ed1d97
  1. 22
      org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/PushCertificateStoreTest.java
  2. 70
      org.eclipse.jgit/src/org/eclipse/jgit/transport/PushCertificateStore.java

22
org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/PushCertificateStoreTest.java

@ -60,7 +60,9 @@ import java.util.concurrent.atomic.AtomicInteger;
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 class PushCertificateStoreTest {
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);

70
org.eclipse.jgit/src/org/eclipse/jgit/transport/PushCertificateStore.java

@ -67,6 +67,7 @@ import org.eclipse.jgit.dircache.DirCacheEditor;
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,22 +327,12 @@ public class PushCertificateStore implements AutoCloseable {
* repository.
*/
public RefUpdate.Result save() throws IOException {
if (pending.isEmpty()) {
ObjectId newId = write();
if (newId == null) {
return RefUpdate.Result.NO_CHANGE;
}
if (reader == null) {
load();
}
sortPending(pending);
ObjectId curr = commit;
DirCache dc = newDirCache();
try (ObjectInserter inserter = db.newObjectInserter()) {
for (PendingCert pc : pending) {
curr = saveCert(inserter, dc, pc, curr);
}
inserter.flush();
RefUpdate.Result result = updateRef(curr);
RefUpdate.Result result = updateRef(newId);
switch (result) {
case FAST_FORWARD:
case NEW:
@ -357,6 +348,59 @@ public class PushCertificateStore implements AutoCloseable {
}
}
/**
* 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();
}
sortPending(pending);
ObjectId curr = commit;
DirCache dc = newDirCache();
try (ObjectInserter inserter = db.newObjectInserter()) {
for (PendingCert pc : pending) {
curr = saveCert(inserter, dc, pc, curr);
}
inserter.flush();
return curr;
}
}
private static void sortPending(List<PendingCert> pending) {
Collections.sort(pending, new Comparator<PendingCert>() {
@Override

Loading…
Cancel
Save