ReceiveCommand.abort(): Utility to mark batch of commands as failed
If one or more commands is failing the entire group usually has to also fail with "transaction aborted". Pull this loop into a helper so the idiom can be easily reused in several places throughout JGit. Change-Id: I3b9399b7e26ce2b0dc5f7baa85d585a433b4eaed
This commit is contained in:
parent
f52581c6a5
commit
eadfcd3ec1
|
@ -16,7 +16,6 @@
|
|||
import java.util.concurrent.locks.ReadWriteLock;
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
||||
|
||||
import org.eclipse.jgit.internal.JGitText;
|
||||
import org.eclipse.jgit.internal.storage.pack.PackExt;
|
||||
import org.eclipse.jgit.lib.BatchRefUpdate;
|
||||
import org.eclipse.jgit.lib.ObjectId;
|
||||
|
@ -312,7 +311,7 @@ private void batch(RevWalk walk, List<ReceiveCommand> cmds) {
|
|||
try (RevWalk rw = new RevWalk(getRepository())) {
|
||||
for (ReceiveCommand c : cmds) {
|
||||
if (c.getResult() != ReceiveCommand.Result.NOT_ATTEMPTED) {
|
||||
reject(cmds);
|
||||
ReceiveCommand.abort(cmds);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -324,7 +323,7 @@ private void batch(RevWalk walk, List<ReceiveCommand> cmds) {
|
|||
}
|
||||
} catch (IOException e) {
|
||||
c.setResult(ReceiveCommand.Result.REJECTED_MISSING_OBJECT);
|
||||
reject(cmds);
|
||||
ReceiveCommand.abort(cmds);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -337,7 +336,7 @@ private void batch(RevWalk walk, List<ReceiveCommand> cmds) {
|
|||
if (r == null) {
|
||||
if (c.getType() != ReceiveCommand.Type.CREATE) {
|
||||
c.setResult(ReceiveCommand.Result.LOCK_FAILURE);
|
||||
reject(cmds);
|
||||
ReceiveCommand.abort(cmds);
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
|
@ -345,7 +344,7 @@ private void batch(RevWalk walk, List<ReceiveCommand> cmds) {
|
|||
if (r.isSymbolic() || objectId == null
|
||||
|| !objectId.equals(c.getOldId())) {
|
||||
c.setResult(ReceiveCommand.Result.LOCK_FAILURE);
|
||||
reject(cmds);
|
||||
ReceiveCommand.abort(cmds);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -374,15 +373,6 @@ private void batch(RevWalk walk, List<ReceiveCommand> cmds) {
|
|||
clearCache();
|
||||
}
|
||||
|
||||
private void reject(List<ReceiveCommand> cmds) {
|
||||
for (ReceiveCommand c : cmds) {
|
||||
if (c.getResult() == ReceiveCommand.Result.NOT_ATTEMPTED) {
|
||||
c.setResult(ReceiveCommand.Result.REJECTED_OTHER_REASON,
|
||||
JGitText.get().transactionAborted);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean compareAndPut(Ref oldRef, Ref newRef)
|
||||
throws IOException {
|
||||
|
|
|
@ -49,12 +49,14 @@
|
|||
import static org.eclipse.jgit.lib.FileMode.TYPE_SYMLINK;
|
||||
import static org.eclipse.jgit.lib.Ref.Storage.NETWORK;
|
||||
import static org.eclipse.jgit.transport.ReceiveCommand.Result.NOT_ATTEMPTED;
|
||||
import static org.eclipse.jgit.transport.ReceiveCommand.Result.REJECTED_OTHER_REASON;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.eclipse.jgit.annotations.Nullable;
|
||||
import org.eclipse.jgit.dircache.DirCacheEntry;
|
||||
import org.eclipse.jgit.errors.MissingObjectException;
|
||||
import org.eclipse.jgit.internal.JGitText;
|
||||
import org.eclipse.jgit.lib.ObjectId;
|
||||
import org.eclipse.jgit.lib.ObjectIdRef;
|
||||
import org.eclipse.jgit.lib.ObjectInserter;
|
||||
|
@ -79,6 +81,30 @@
|
|||
* for processing.
|
||||
*/
|
||||
public class Command {
|
||||
/**
|
||||
* Set unprocessed commands as failed due to transaction aborted.
|
||||
* <p>
|
||||
* If a command is still {@link Result#NOT_ATTEMPTED} it will be set to
|
||||
* {@link Result#REJECTED_OTHER_REASON}. If {@code why} is non-null its
|
||||
* contents will be used as the message for the first command status.
|
||||
*
|
||||
* @param commands
|
||||
* commands to mark as failed.
|
||||
* @param why
|
||||
* optional message to set on the first aborted command.
|
||||
*/
|
||||
public static void abort(Iterable<Command> commands, @Nullable String why) {
|
||||
if (why == null || why.isEmpty()) {
|
||||
why = JGitText.get().transactionAborted;
|
||||
}
|
||||
for (Command c : commands) {
|
||||
if (c.getResult() == NOT_ATTEMPTED) {
|
||||
c.setResult(REJECTED_OTHER_REASON, why);
|
||||
why = JGitText.get().transactionAborted;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private final Ref oldRef;
|
||||
private final Ref newRef;
|
||||
private final ReceiveCommand cmd;
|
||||
|
|
|
@ -55,7 +55,6 @@
|
|||
import static org.eclipse.jgit.lib.Ref.Storage.PACKED;
|
||||
import static org.eclipse.jgit.lib.RefDatabase.MAX_SYMBOLIC_REF_DEPTH;
|
||||
import static org.eclipse.jgit.transport.ReceiveCommand.Result.LOCK_FAILURE;
|
||||
import static org.eclipse.jgit.transport.ReceiveCommand.Result.NOT_ATTEMPTED;
|
||||
import static org.eclipse.jgit.transport.ReceiveCommand.Result.REJECTED_OTHER_REASON;
|
||||
|
||||
import java.io.IOException;
|
||||
|
@ -248,7 +247,8 @@ public boolean apply(Collection<Command> cmdList) {
|
|||
if (!isValidRef(cmd)) {
|
||||
cmd.setResult(REJECTED_OTHER_REASON,
|
||||
JGitText.get().funnyRefname);
|
||||
return abort(cmdList);
|
||||
Command.abort(cmdList, null);
|
||||
return false;
|
||||
}
|
||||
apply(ed, cmd);
|
||||
}
|
||||
|
@ -264,9 +264,11 @@ public boolean apply(Collection<Command> cmdList) {
|
|||
break;
|
||||
}
|
||||
}
|
||||
return abort(cmdList);
|
||||
Command.abort(cmdList, null);
|
||||
return false;
|
||||
} catch (LockFailureException e) {
|
||||
return abort(cmdList);
|
||||
Command.abort(cmdList, null);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -342,19 +344,6 @@ private static void cleanupPeeledRef(DirCacheEditor ed, Ref ref) {
|
|||
}
|
||||
}
|
||||
|
||||
private static boolean abort(Iterable<Command> cmdList) {
|
||||
for (Command cmd : cmdList) {
|
||||
if (cmd.getResult() == NOT_ATTEMPTED) {
|
||||
reject(cmd, JGitText.get().transactionAborted);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static void reject(Command cmd, String msg) {
|
||||
cmd.setResult(REJECTED_OTHER_REASON, msg);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a path name in a RefTree to the reference name known by Git.
|
||||
*
|
||||
|
|
|
@ -98,7 +98,7 @@ public void execute(RevWalk rw, ProgressMonitor monitor)
|
|||
}
|
||||
if (c.getType() == UPDATE_NONFASTFORWARD) {
|
||||
c.setResult(REJECTED_NONFASTFORWARD);
|
||||
reject();
|
||||
ReceiveCommand.abort(getCommands());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -108,15 +108,6 @@ public void execute(RevWalk rw, ProgressMonitor monitor)
|
|||
execute(rw, todo);
|
||||
}
|
||||
|
||||
private void reject() {
|
||||
String aborted = JGitText.get().transactionAborted;
|
||||
for (ReceiveCommand c : getCommands()) {
|
||||
if (c.getResult() == NOT_ATTEMPTED) {
|
||||
c.setResult(REJECTED_OTHER_REASON, aborted);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void init(RevWalk rw) throws IOException {
|
||||
src = refdb.getBootstrap().exactRef(refdb.getTxnCommitted());
|
||||
if (src != null && src.getObjectId() != null) {
|
||||
|
@ -150,13 +141,13 @@ Ref exactRef(ObjectReader reader, String name) throws IOException {
|
|||
void execute(RevWalk rw, List<Command> todo) throws IOException {
|
||||
for (Command c : todo) {
|
||||
if (c.getResult() != NOT_ATTEMPTED) {
|
||||
reject(todo, JGitText.get().transactionAborted);
|
||||
Command.abort(todo, null);
|
||||
return;
|
||||
}
|
||||
if (refdb.conflictsWithBootstrap(c.getRefName())) {
|
||||
c.setResult(REJECTED_OTHER_REASON, MessageFormat
|
||||
.format(JGitText.get().invalidRefName, c.getRefName()));
|
||||
reject(todo, JGitText.get().transactionAborted);
|
||||
Command.abort(todo, null);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -210,7 +201,7 @@ private void commit(RevWalk rw, List<Command> todo) throws IOException {
|
|||
c.setResult(OK);
|
||||
}
|
||||
} else {
|
||||
reject(todo, commit.getResult().name());
|
||||
Command.abort(todo, commit.getResult().name());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -228,13 +219,4 @@ private void updateBootstrap(RevWalk rw, ReceiveCommand commit)
|
|||
u.addCommand(commit);
|
||||
u.execute(rw, NullProgressMonitor.INSTANCE);
|
||||
}
|
||||
|
||||
private static void reject(List<Command> todo, String msg) {
|
||||
for (Command c : todo) {
|
||||
if (c.getResult() == NOT_ATTEMPTED) {
|
||||
c.setResult(REJECTED_OTHER_REASON, msg);
|
||||
msg = JGitText.get().transactionAborted;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1453,10 +1453,7 @@ protected boolean anyRejects() {
|
|||
* @since 3.6
|
||||
*/
|
||||
protected void failPendingCommands() {
|
||||
for (ReceiveCommand cmd : commands) {
|
||||
if (cmd.getResult() == Result.NOT_ATTEMPTED)
|
||||
cmd.setResult(Result.REJECTED_OTHER_REASON, JGitText.get().transactionAborted);
|
||||
}
|
||||
ReceiveCommand.abort(commands);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -43,6 +43,9 @@
|
|||
|
||||
package org.eclipse.jgit.transport;
|
||||
|
||||
import static org.eclipse.jgit.transport.ReceiveCommand.Result.NOT_ATTEMPTED;
|
||||
import static org.eclipse.jgit.transport.ReceiveCommand.Result.REJECTED_OTHER_REASON;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.text.MessageFormat;
|
||||
import java.util.ArrayList;
|
||||
|
@ -168,6 +171,25 @@ public static List<ReceiveCommand> filter(List<ReceiveCommand> commands,
|
|||
return filter((Iterable<ReceiveCommand>) commands, want);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set unprocessed commands as failed due to transaction aborted.
|
||||
* <p>
|
||||
* If a command is still {@link Result#NOT_ATTEMPTED} it will be set to
|
||||
* {@link Result#REJECTED_OTHER_REASON}.
|
||||
*
|
||||
* @param commands
|
||||
* commands to mark as failed.
|
||||
* @since 4.2
|
||||
*/
|
||||
public static void abort(Iterable<ReceiveCommand> commands) {
|
||||
for (ReceiveCommand c : commands) {
|
||||
if (c.getResult() == NOT_ATTEMPTED) {
|
||||
c.setResult(REJECTED_OTHER_REASON,
|
||||
JGitText.get().transactionAborted);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private final ObjectId oldId;
|
||||
|
||||
private final ObjectId newId;
|
||||
|
|
Loading…
Reference in New Issue