diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/BatchRefUpdateTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/BatchRefUpdateTest.java
index 3cfc82d..06c47ac 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/BatchRefUpdateTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/BatchRefUpdateTest.java
@@ -43,22 +43,35 @@
 
 package org.eclipse.jgit.internal.storage.file;
 
+import static org.eclipse.jgit.internal.storage.file.BatchRefUpdateTest.Result.LOCK_FAILURE;
+import static org.eclipse.jgit.internal.storage.file.BatchRefUpdateTest.Result.OK;
+import static org.eclipse.jgit.internal.storage.file.BatchRefUpdateTest.Result.REJECTED_MISSING_OBJECT;
+import static org.eclipse.jgit.internal.storage.file.BatchRefUpdateTest.Result.REJECTED_NONFASTFORWARD;
+import static org.eclipse.jgit.internal.storage.file.BatchRefUpdateTest.Result.TRANSACTION_ABORTED;
 import static org.eclipse.jgit.lib.ObjectId.zeroId;
+import static org.eclipse.jgit.transport.ReceiveCommand.Type.CREATE;
+import static org.eclipse.jgit.transport.ReceiveCommand.Type.DELETE;
+import static org.eclipse.jgit.transport.ReceiveCommand.Type.UPDATE;
+import static org.eclipse.jgit.transport.ReceiveCommand.Type.UPDATE_NONFASTFORWARD;
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertTrue;
 
 import java.io.File;
 import java.io.IOException;
 import java.util.Arrays;
 import java.util.Collection;
+import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.function.Predicate;
 
 import org.eclipse.jgit.junit.LocalDiskRepositoryTestCase;
 import org.eclipse.jgit.junit.StrictWorkMonitor;
 import org.eclipse.jgit.junit.TestRepository;
 import org.eclipse.jgit.lib.AnyObjectId;
 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.Ref;
@@ -103,43 +116,26 @@
 		B = repo.commit(repo.getRevWalk().parseCommit(A));
 	}
 
-	private BatchRefUpdate newBatchUpdate() {
-		BatchRefUpdate u = refdir.newBatchUpdate();
-		if (atomic) {
-			assertTrue(u.isAtomic());
-		} else {
-			u.setAtomic(false);
-		}
-		return u;
-	}
-
 	@Test
 	public void simpleNoForce() throws IOException {
 		writeLooseRef("refs/heads/master", A);
 		writeLooseRef("refs/heads/masters", B);
-		List<ReceiveCommand> commands = Arrays.asList(
-				new ReceiveCommand(A, B, "refs/heads/master",
-						ReceiveCommand.Type.UPDATE),
-				new ReceiveCommand(B, A, "refs/heads/masters",
-						ReceiveCommand.Type.UPDATE_NONFASTFORWARD));
-		BatchRefUpdate batchUpdate = newBatchUpdate();
-		batchUpdate.addCommand(commands);
-		batchUpdate.execute(new RevWalk(diskRepo), new StrictWorkMonitor());
-		Map<String, Ref> refs = refdir.getRefs(RefDatabase.ALL);
-		assertEquals(ReceiveCommand.Result.REJECTED_NONFASTFORWARD, commands
-				.get(1).getResult());
+
+		List<ReceiveCommand> cmds = Arrays.asList(
+				new ReceiveCommand(A, B, "refs/heads/master", UPDATE),
+				new ReceiveCommand(B, A, "refs/heads/masters", UPDATE_NONFASTFORWARD));
+		execute(newBatchUpdate(cmds));
+
 		if (atomic) {
-			assertTrue(ReceiveCommand.isTransactionAborted(commands.get(0)));
-			assertEquals("[HEAD, refs/heads/master, refs/heads/masters]", refs
-					.keySet().toString());
-			assertEquals(A.getId(), refs.get("refs/heads/master").getObjectId());
-			assertEquals(B.getId(), refs.get("refs/heads/masters").getObjectId());
+			assertResults(cmds, TRANSACTION_ABORTED, REJECTED_NONFASTFORWARD);
+			assertRefs(
+					"refs/heads/master", A,
+					"refs/heads/masters", B);
 		} else {
-			assertEquals(ReceiveCommand.Result.OK, commands.get(0).getResult());
-			assertEquals("[HEAD, refs/heads/master, refs/heads/masters]", refs
-					.keySet().toString());
-			assertEquals(B.getId(), refs.get("refs/heads/master").getObjectId());
-			assertEquals(B.getId(), refs.get("refs/heads/masters").getObjectId());
+			assertResults(cmds, OK, REJECTED_NONFASTFORWARD);
+			assertRefs(
+					"refs/heads/master", B,
+					"refs/heads/masters", B);
 		}
 	}
 
@@ -147,85 +143,65 @@
 	public void simpleForce() throws IOException {
 		writeLooseRef("refs/heads/master", A);
 		writeLooseRef("refs/heads/masters", B);
-		List<ReceiveCommand> commands = Arrays.asList(
-				new ReceiveCommand(A, B, "refs/heads/master",
-						ReceiveCommand.Type.UPDATE),
-				new ReceiveCommand(B, A, "refs/heads/masters",
-						ReceiveCommand.Type.UPDATE_NONFASTFORWARD));
-		BatchRefUpdate batchUpdate = newBatchUpdate();
-		batchUpdate.setAllowNonFastForwards(true);
-		batchUpdate.addCommand(commands);
-		batchUpdate.execute(new RevWalk(diskRepo), new StrictWorkMonitor());
-		Map<String, Ref> refs = refdir.getRefs(RefDatabase.ALL);
-		assertEquals(ReceiveCommand.Result.OK, commands.get(0).getResult());
-		assertEquals(ReceiveCommand.Result.OK, commands.get(1).getResult());
-		assertEquals("[HEAD, refs/heads/master, refs/heads/masters]", refs
-				.keySet().toString());
-		assertEquals(B.getId(), refs.get("refs/heads/master").getObjectId());
-		assertEquals(A.getId(), refs.get("refs/heads/masters").getObjectId());
+
+		List<ReceiveCommand> cmds = Arrays.asList(
+				new ReceiveCommand(A, B, "refs/heads/master", UPDATE),
+				new ReceiveCommand(B, A, "refs/heads/masters", UPDATE_NONFASTFORWARD));
+		execute(newBatchUpdate(cmds).setAllowNonFastForwards(true));
+
+		assertResults(cmds, OK, OK);
+		assertRefs(
+				"refs/heads/master", B,
+				"refs/heads/masters", A);
 	}
 
 	@Test
 	public void nonFastForwardDoesNotDoExpensiveMergeCheck() throws IOException {
 		writeLooseRef("refs/heads/master", B);
-		List<ReceiveCommand> commands = Arrays.asList(
-				new ReceiveCommand(B, A, "refs/heads/master",
-						ReceiveCommand.Type.UPDATE_NONFASTFORWARD));
-		BatchRefUpdate batchUpdate = newBatchUpdate();
-		batchUpdate.setAllowNonFastForwards(true);
-		batchUpdate.addCommand(commands);
-		batchUpdate.execute(new RevWalk(diskRepo) {
-			@Override
-			public boolean isMergedInto(RevCommit base, RevCommit tip) {
-				throw new AssertionError("isMergedInto() should not be called");
-			}
-		}, new StrictWorkMonitor());
-		Map<String, Ref> refs = refdir.getRefs(RefDatabase.ALL);
-		assertEquals(ReceiveCommand.Result.OK, commands.get(0).getResult());
-		assertEquals(A.getId(), refs.get("refs/heads/master").getObjectId());
+
+		List<ReceiveCommand> cmds = Arrays.asList(
+				new ReceiveCommand(B, A, "refs/heads/master", UPDATE_NONFASTFORWARD));
+		try (RevWalk rw = new RevWalk(diskRepo) {
+					@Override
+					public boolean isMergedInto(RevCommit base, RevCommit tip) {
+						throw new AssertionError("isMergedInto() should not be called");
+					}
+				}) {
+			newBatchUpdate(cmds)
+					.setAllowNonFastForwards(true)
+					.execute(rw, new StrictWorkMonitor());
+		}
+
+		assertResults(cmds, OK);
+		assertRefs("refs/heads/master", A);
 	}
 
 	@Test
 	public void fileDirectoryConflict() throws IOException {
 		writeLooseRef("refs/heads/master", A);
 		writeLooseRef("refs/heads/masters", B);
-		List<ReceiveCommand> commands = Arrays.asList(
-				new ReceiveCommand(A, B, "refs/heads/master",
-						ReceiveCommand.Type.UPDATE),
-				new ReceiveCommand(zeroId(), A, "refs/heads/master/x",
-						ReceiveCommand.Type.CREATE),
-				new ReceiveCommand(zeroId(), A, "refs/heads",
-						ReceiveCommand.Type.CREATE));
-		BatchRefUpdate batchUpdate = newBatchUpdate();
-		batchUpdate.setAllowNonFastForwards(true);
-		batchUpdate.addCommand(commands);
-		batchUpdate
-				.execute(new RevWalk(diskRepo), NullProgressMonitor.INSTANCE);
-		Map<String, Ref> refs = refdir.getRefs(RefDatabase.ALL);
+
+		List<ReceiveCommand> cmds = Arrays.asList(
+				new ReceiveCommand(A, B, "refs/heads/master", UPDATE),
+				new ReceiveCommand(zeroId(), A, "refs/heads/master/x", CREATE),
+				new ReceiveCommand(zeroId(), A, "refs/heads", CREATE));
+		execute(newBatchUpdate(cmds).setAllowNonFastForwards(true), false);
 
 		if (atomic) {
 			// Atomic update sees that master and master/x are conflicting, then marks
 			// the first one in the list as LOCK_FAILURE and aborts the rest.
-			assertEquals(ReceiveCommand.Result.LOCK_FAILURE,
-					commands.get(0).getResult());
-			assertTrue(ReceiveCommand.isTransactionAborted(commands.get(1)));
-			assertTrue(ReceiveCommand.isTransactionAborted(commands.get(2)));
-			assertEquals("[HEAD, refs/heads/master, refs/heads/masters]", refs
-					.keySet().toString());
-			assertEquals(A.getId(), refs.get("refs/heads/master").getObjectId());
-			assertEquals(B.getId(), refs.get("refs/heads/masters").getObjectId());
+			assertResults(cmds,
+					LOCK_FAILURE, TRANSACTION_ABORTED, TRANSACTION_ABORTED);
+			assertRefs(
+					"refs/heads/master", A,
+					"refs/heads/masters", B);
 		} else {
 			// Non-atomic updates are applied in order: master succeeds, then master/x
 			// fails due to conflict.
-			assertEquals(ReceiveCommand.Result.OK, commands.get(0).getResult());
-			assertEquals(ReceiveCommand.Result.LOCK_FAILURE, commands.get(1)
-					.getResult());
-			assertEquals(ReceiveCommand.Result.LOCK_FAILURE, commands.get(2)
-					.getResult());
-			assertEquals("[HEAD, refs/heads/master, refs/heads/masters]", refs
-					.keySet().toString());
-			assertEquals(B.getId(), refs.get("refs/heads/master").getObjectId());
-			assertEquals(B.getId(), refs.get("refs/heads/masters").getObjectId());
+			assertResults(cmds, OK, LOCK_FAILURE, LOCK_FAILURE);
+			assertRefs(
+					"refs/heads/master", B,
+					"refs/heads/masters", B);
 		}
 	}
 
@@ -233,170 +209,205 @@
 	public void conflictThanksToDelete() throws IOException {
 		writeLooseRef("refs/heads/master", A);
 		writeLooseRef("refs/heads/masters", B);
-		List<ReceiveCommand> commands = Arrays.asList(
-				new ReceiveCommand(A, B, "refs/heads/master",
-						ReceiveCommand.Type.UPDATE),
-				new ReceiveCommand(zeroId(), A, "refs/heads/masters/x",
-						ReceiveCommand.Type.CREATE),
-				new ReceiveCommand(B, zeroId(), "refs/heads/masters",
-						ReceiveCommand.Type.DELETE));
-		BatchRefUpdate batchUpdate = newBatchUpdate();
-		batchUpdate.setAllowNonFastForwards(true);
-		batchUpdate.addCommand(commands);
-		batchUpdate.execute(new RevWalk(diskRepo), new StrictWorkMonitor());
-		Map<String, Ref> refs = refdir.getRefs(RefDatabase.ALL);
-		assertEquals(ReceiveCommand.Result.OK, commands.get(0).getResult());
-		assertEquals(ReceiveCommand.Result.OK, commands.get(1).getResult());
-		assertEquals(ReceiveCommand.Result.OK, commands.get(2).getResult());
-		assertEquals("[HEAD, refs/heads/master, refs/heads/masters/x]", refs
-				.keySet().toString());
-		assertEquals(A.getId(), refs.get("refs/heads/masters/x").getObjectId());
+
+		List<ReceiveCommand> cmds = Arrays.asList(
+				new ReceiveCommand(A, B, "refs/heads/master", UPDATE),
+				new ReceiveCommand(zeroId(), A, "refs/heads/masters/x", CREATE),
+				new ReceiveCommand(B, zeroId(), "refs/heads/masters", DELETE));
+		execute(newBatchUpdate(cmds).setAllowNonFastForwards(true));
+
+		assertResults(cmds, OK, OK, OK);
+		assertRefs(
+				"refs/heads/master", B,
+				"refs/heads/masters/x", A);
 	}
 
 	@Test
 	public void updateToMissingObject() throws IOException {
 		writeLooseRef("refs/heads/master", A);
+
 		ObjectId bad =
 				ObjectId.fromString("deadbeefdeadbeefdeadbeefdeadbeefdeadbeef");
-		List<ReceiveCommand> commands = Arrays.asList(
-				new ReceiveCommand(A, bad, "refs/heads/master",
-						ReceiveCommand.Type.UPDATE),
-				new ReceiveCommand(zeroId(), B, "refs/heads/foo2",
-						ReceiveCommand.Type.CREATE));
-		BatchRefUpdate batchUpdate = newBatchUpdate();
-		batchUpdate.setAllowNonFastForwards(true);
-		batchUpdate.addCommand(commands);
-		batchUpdate.execute(new RevWalk(diskRepo), NullProgressMonitor.INSTANCE);
-		Map<String, Ref> refs = refdir.getRefs(RefDatabase.ALL);
-		assertEquals(ReceiveCommand.Result.REJECTED_MISSING_OBJECT,
-				commands.get(0).getResult());
+		List<ReceiveCommand> cmds = Arrays.asList(
+				new ReceiveCommand(A, bad, "refs/heads/master", UPDATE),
+				new ReceiveCommand(zeroId(), B, "refs/heads/foo2", CREATE));
+		execute(newBatchUpdate(cmds).setAllowNonFastForwards(true), false);
 
 		if (atomic) {
-			assertTrue(ReceiveCommand.isTransactionAborted(commands.get(1)));
-			assertEquals("[HEAD, refs/heads/master]", refs.keySet()
-					.toString());
-			assertEquals(A.getId(), refs.get("refs/heads/master").getObjectId());
+			assertResults(cmds, REJECTED_MISSING_OBJECT, TRANSACTION_ABORTED);
+			assertRefs("refs/heads/master", A);
 		} else {
-			assertEquals(ReceiveCommand.Result.OK, commands.get(1).getResult());
-			assertEquals("[HEAD, refs/heads/foo2, refs/heads/master]", refs.keySet()
-					.toString());
-			assertEquals(A.getId(), refs.get("refs/heads/master").getObjectId());
-			assertEquals(B.getId(), refs.get("refs/heads/foo2").getObjectId());
+			assertResults(cmds, REJECTED_MISSING_OBJECT, OK);
+			assertRefs(
+					"refs/heads/master", A,
+					"refs/heads/foo2", B);
 		}
 	}
 
 	@Test
 	public void addMissingObject() throws IOException {
 		writeLooseRef("refs/heads/master", A);
+
 		ObjectId bad =
 				ObjectId.fromString("deadbeefdeadbeefdeadbeefdeadbeefdeadbeef");
-		List<ReceiveCommand> commands = Arrays.asList(
-				new ReceiveCommand(A, B, "refs/heads/master",
-						ReceiveCommand.Type.UPDATE),
-				new ReceiveCommand(zeroId(), bad, "refs/heads/foo2",
-						ReceiveCommand.Type.CREATE));
-		BatchRefUpdate batchUpdate = newBatchUpdate();
-		batchUpdate.setAllowNonFastForwards(true);
-		batchUpdate.addCommand(commands);
-		batchUpdate.execute(new RevWalk(diskRepo), NullProgressMonitor.INSTANCE);
-		Map<String, Ref> refs = refdir.getRefs(RefDatabase.ALL);
-		assertEquals(ReceiveCommand.Result.REJECTED_MISSING_OBJECT,
-				commands.get(1).getResult());
+		List<ReceiveCommand> cmds = Arrays.asList(
+				new ReceiveCommand(A, B, "refs/heads/master", UPDATE),
+				new ReceiveCommand(zeroId(), bad, "refs/heads/foo2", CREATE));
+		execute(newBatchUpdate(cmds).setAllowNonFastForwards(true), false);
 
 		if (atomic) {
-			assertTrue(ReceiveCommand.isTransactionAborted(commands.get(0)));
-			assertEquals("[HEAD, refs/heads/master]", refs.keySet().toString());
-			assertEquals(A.getId(), refs.get("refs/heads/master").getObjectId());
+			assertResults(cmds, TRANSACTION_ABORTED, REJECTED_MISSING_OBJECT);
+			assertRefs("refs/heads/master", A);
 		} else {
-			assertEquals(ReceiveCommand.Result.OK, commands.get(0).getResult());
-			assertEquals("[HEAD, refs/heads/master]", refs.keySet()
-					.toString());
-			assertEquals(B.getId(), refs.get("refs/heads/master").getObjectId());
+			assertResults(cmds, OK, REJECTED_MISSING_OBJECT);
+			assertRefs("refs/heads/master", B);
 		}
 	}
 
 	@Test
 	public void oneNonExistentRef() throws IOException {
-		List<ReceiveCommand> commands = Arrays.asList(
-				new ReceiveCommand(A, B, "refs/heads/foo1",
-						ReceiveCommand.Type.UPDATE),
-				new ReceiveCommand(zeroId(), B, "refs/heads/foo2",
-						ReceiveCommand.Type.CREATE));
-		BatchRefUpdate batchUpdate = newBatchUpdate();
-		batchUpdate.setAllowNonFastForwards(true);
-		batchUpdate.addCommand(commands);
-		batchUpdate.execute(new RevWalk(diskRepo), new StrictWorkMonitor());
-		Map<String, Ref> refs = refdir.getRefs(RefDatabase.ALL);
-		assertEquals(ReceiveCommand.Result.LOCK_FAILURE,
-				commands.get(0).getResult());
+		List<ReceiveCommand> cmds = Arrays.asList(
+				new ReceiveCommand(A, B, "refs/heads/foo1", UPDATE),
+				new ReceiveCommand(zeroId(), B, "refs/heads/foo2", CREATE));
+		execute(newBatchUpdate(cmds).setAllowNonFastForwards(true));
 
 		if (atomic) {
-			assertTrue(ReceiveCommand.isTransactionAborted(commands.get(1)));
-			assertEquals("[]", refs.keySet().toString());
+			assertResults(cmds, LOCK_FAILURE, TRANSACTION_ABORTED);
+			assertRefs();
 		} else {
-			assertEquals(ReceiveCommand.Result.OK, commands.get(1).getResult());
-			assertEquals("[refs/heads/foo2]", refs.keySet().toString());
-			assertEquals(B.getId(), refs.get("refs/heads/foo2").getObjectId());
+			assertResults(cmds, LOCK_FAILURE, OK);
+			assertRefs("refs/heads/foo2", B);
 		}
 	}
 
 	@Test
 	public void oneRefWrongOldValue() throws IOException {
 		writeLooseRef("refs/heads/master", A);
-		List<ReceiveCommand> commands = Arrays.asList(
-				new ReceiveCommand(B, B, "refs/heads/master",
-						ReceiveCommand.Type.UPDATE),
-				new ReceiveCommand(zeroId(), B, "refs/heads/foo2",
-						ReceiveCommand.Type.CREATE));
-		BatchRefUpdate batchUpdate = newBatchUpdate();
-		batchUpdate.setAllowNonFastForwards(true);
-		batchUpdate.addCommand(commands);
-		batchUpdate.execute(new RevWalk(diskRepo), new StrictWorkMonitor());
-		Map<String, Ref> refs = refdir.getRefs(RefDatabase.ALL);
-		assertEquals(ReceiveCommand.Result.LOCK_FAILURE,
-				commands.get(0).getResult());
+
+		List<ReceiveCommand> cmds = Arrays.asList(
+				new ReceiveCommand(B, B, "refs/heads/master", UPDATE),
+				new ReceiveCommand(zeroId(), B, "refs/heads/foo2", CREATE));
+		execute(newBatchUpdate(cmds).setAllowNonFastForwards(true));
 
 		if (atomic) {
-			assertTrue(ReceiveCommand.isTransactionAborted(commands.get(1)));
-			assertEquals("[HEAD, refs/heads/master]", refs.keySet().toString());
-			assertEquals(A.getId(), refs.get("refs/heads/master").getObjectId());
+			assertResults(cmds, LOCK_FAILURE, TRANSACTION_ABORTED);
+			assertRefs("refs/heads/master", A);
 		} else {
-			assertEquals(ReceiveCommand.Result.OK, commands.get(1).getResult());
-			assertEquals("[HEAD, refs/heads/foo2, refs/heads/master]", refs
-					.keySet().toString());
-			assertEquals(A.getId(), refs.get("refs/heads/master").getObjectId());
-			assertEquals(B.getId(), refs.get("refs/heads/foo2").getObjectId());
+			assertResults(cmds, LOCK_FAILURE, OK);
+			assertRefs(
+					"refs/heads/master", A,
+					"refs/heads/foo2", B);
 		}
 	}
 
 	@Test
 	public void nonExistentRef() throws IOException {
 		writeLooseRef("refs/heads/master", A);
-		List<ReceiveCommand> commands = Arrays.asList(
-				new ReceiveCommand(A, B, "refs/heads/master",
-						ReceiveCommand.Type.UPDATE),
-				new ReceiveCommand(A, zeroId(), "refs/heads/foo2",
-						ReceiveCommand.Type.DELETE));
-		BatchRefUpdate batchUpdate = newBatchUpdate();
-		batchUpdate.setAllowNonFastForwards(true);
-		batchUpdate.addCommand(commands);
-		batchUpdate.execute(new RevWalk(diskRepo), new StrictWorkMonitor());
-		Map<String, Ref> refs = refdir.getRefs(RefDatabase.ALL);
-		assertEquals(ReceiveCommand.Result.LOCK_FAILURE,
-				commands.get(1).getResult());
+
+		List<ReceiveCommand> cmds = Arrays.asList(
+				new ReceiveCommand(A, B, "refs/heads/master", UPDATE),
+				new ReceiveCommand(A, zeroId(), "refs/heads/foo2", DELETE));
+		execute(newBatchUpdate(cmds).setAllowNonFastForwards(true));
 
 		if (atomic) {
-			assertTrue(ReceiveCommand.isTransactionAborted(commands.get(0)));
-			assertEquals("[HEAD, refs/heads/master]", refs.keySet().toString());
-			assertEquals(A.getId(), refs.get("refs/heads/master").getObjectId());
+			assertResults(cmds, TRANSACTION_ABORTED, LOCK_FAILURE);
+			assertRefs("refs/heads/master", A);
 		} else {
-			assertEquals(ReceiveCommand.Result.OK, commands.get(0).getResult());
-			assertEquals("[HEAD, refs/heads/master]", refs.keySet().toString());
-			assertEquals(B.getId(), refs.get("refs/heads/master").getObjectId());
+			assertResults(cmds, OK, LOCK_FAILURE);
+			assertRefs("refs/heads/master", B);
 		}
 	}
 
 	private void writeLooseRef(String name, AnyObjectId id) throws IOException {
 		write(new File(diskRepo.getDirectory(), name), id.name() + "\n");
 	}
+
+	private BatchRefUpdate newBatchUpdate(List<ReceiveCommand> cmds) {
+		BatchRefUpdate u = refdir.newBatchUpdate();
+		if (atomic) {
+			assertTrue(u.isAtomic());
+		} else {
+			u.setAtomic(false);
+		}
+		u.addCommand(cmds);
+		return u;
+	}
+
+	private void execute(BatchRefUpdate u) throws IOException {
+		execute(u, false);
+	}
+
+	private void execute(BatchRefUpdate u, boolean strictWork) throws IOException {
+		try (RevWalk rw = new RevWalk(diskRepo)) {
+			u.execute(rw,
+					strictWork ? new StrictWorkMonitor() : NullProgressMonitor.INSTANCE);
+		}
+	}
+
+	private void assertRefs(Object... args) throws IOException {
+		if (args.length % 2 != 0) {
+			throw new IllegalArgumentException(
+					"expected even number of args: " + Arrays.toString(args));
+		}
+
+		Map<String, AnyObjectId> expected = new LinkedHashMap<>();
+		for (int i = 0; i < args.length; i += 2) {
+			expected.put((String) args[i], (AnyObjectId) args[i + 1]);
+		}
+
+		Map<String, Ref> refs = refdir.getRefs(RefDatabase.ALL);
+		Ref actualHead = refs.remove(Constants.HEAD);
+		if (actualHead != null) {
+			String actualLeafName = actualHead.getLeaf().getName();
+			assertEquals(
+					"expected HEAD to point to refs/heads/master, got: " + actualLeafName,
+					"refs/heads/master", actualLeafName);
+			AnyObjectId expectedMaster = expected.get("refs/heads/master");
+			assertNotNull("expected master ref since HEAD exists", expectedMaster);
+			assertEquals(expectedMaster, actualHead.getObjectId());
+		}
+
+		Map<String, AnyObjectId> actual = new LinkedHashMap<>();
+		refs.forEach((n, r) -> actual.put(n, r.getObjectId()));
+
+		assertEquals(expected.keySet(), actual.keySet());
+		actual.forEach((n, a) -> assertEquals(n, expected.get(n), a));
+	}
+
+	enum Result {
+		OK(ReceiveCommand.Result.OK),
+		LOCK_FAILURE(ReceiveCommand.Result.LOCK_FAILURE),
+		REJECTED_NONFASTFORWARD(ReceiveCommand.Result.REJECTED_NONFASTFORWARD),
+		REJECTED_MISSING_OBJECT(ReceiveCommand.Result.REJECTED_MISSING_OBJECT),
+		TRANSACTION_ABORTED(ReceiveCommand::isTransactionAborted);
+
+		final Predicate<? super ReceiveCommand> p;
+
+		private Result(Predicate<? super ReceiveCommand> p) {
+			this.p = p;
+		}
+
+		private Result(ReceiveCommand.Result result) {
+			this(c -> c.getResult() == result);
+		}
+	}
+
+	private void assertResults(
+			List<ReceiveCommand> cmds, Result... expected) {
+		if (expected.length != cmds.size()) {
+			throw new IllegalArgumentException(
+					"expected " + cmds.size() + " result args");
+		}
+		for (int i = 0; i < cmds.size(); i++) {
+			ReceiveCommand c = cmds.get(i);
+			Result r = expected[i];
+			assertTrue(
+					String.format(
+							"result of command (%d) should be %s: %s %s%s",
+							Integer.valueOf(i), r, c,
+							c.getResult(),
+							c.getMessage() != null ? " (" + c.getMessage() + ")" : ""),
+					r.p.test(c));
+		}
+	}
 }
