Browse Source

Merge "ReceiveCommand.abort(): Utility to mark batch of commands as failed"

tags/v4.2.0.201601211800-r
Shawn Pearce 8 years ago
parent
commit
9d3b56a905

+ 4
- 14
org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/InMemoryRepository.java View File

import java.util.concurrent.locks.ReadWriteLock; import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock; import java.util.concurrent.locks.ReentrantReadWriteLock;


import org.eclipse.jgit.internal.JGitText;
import org.eclipse.jgit.internal.storage.pack.PackExt; import org.eclipse.jgit.internal.storage.pack.PackExt;
import org.eclipse.jgit.lib.BatchRefUpdate; import org.eclipse.jgit.lib.BatchRefUpdate;
import org.eclipse.jgit.lib.ObjectId; import org.eclipse.jgit.lib.ObjectId;
try (RevWalk rw = new RevWalk(getRepository())) { try (RevWalk rw = new RevWalk(getRepository())) {
for (ReceiveCommand c : cmds) { for (ReceiveCommand c : cmds) {
if (c.getResult() != ReceiveCommand.Result.NOT_ATTEMPTED) { if (c.getResult() != ReceiveCommand.Result.NOT_ATTEMPTED) {
reject(cmds);
ReceiveCommand.abort(cmds);
return; return;
} }


} }
} catch (IOException e) { } catch (IOException e) {
c.setResult(ReceiveCommand.Result.REJECTED_MISSING_OBJECT); c.setResult(ReceiveCommand.Result.REJECTED_MISSING_OBJECT);
reject(cmds);
ReceiveCommand.abort(cmds);
return; return;
} }
} }
if (r == null) { if (r == null) {
if (c.getType() != ReceiveCommand.Type.CREATE) { if (c.getType() != ReceiveCommand.Type.CREATE) {
c.setResult(ReceiveCommand.Result.LOCK_FAILURE); c.setResult(ReceiveCommand.Result.LOCK_FAILURE);
reject(cmds);
ReceiveCommand.abort(cmds);
return; return;
} }
} else { } else {
if (r.isSymbolic() || objectId == null if (r.isSymbolic() || objectId == null
|| !objectId.equals(c.getOldId())) { || !objectId.equals(c.getOldId())) {
c.setResult(ReceiveCommand.Result.LOCK_FAILURE); c.setResult(ReceiveCommand.Result.LOCK_FAILURE);
reject(cmds);
ReceiveCommand.abort(cmds);
return; return;
} }
} }
clearCache(); 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 @Override
protected boolean compareAndPut(Ref oldRef, Ref newRef) protected boolean compareAndPut(Ref oldRef, Ref newRef)
throws IOException { throws IOException {

+ 26
- 0
org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/reftree/Command.java View File

import static org.eclipse.jgit.lib.FileMode.TYPE_SYMLINK; import static org.eclipse.jgit.lib.FileMode.TYPE_SYMLINK;
import static org.eclipse.jgit.lib.Ref.Storage.NETWORK; 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.NOT_ATTEMPTED;
import static org.eclipse.jgit.transport.ReceiveCommand.Result.REJECTED_OTHER_REASON;


import java.io.IOException; import java.io.IOException;


import org.eclipse.jgit.annotations.Nullable; import org.eclipse.jgit.annotations.Nullable;
import org.eclipse.jgit.dircache.DirCacheEntry; import org.eclipse.jgit.dircache.DirCacheEntry;
import org.eclipse.jgit.errors.MissingObjectException; import org.eclipse.jgit.errors.MissingObjectException;
import org.eclipse.jgit.internal.JGitText;
import org.eclipse.jgit.lib.ObjectId; import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.ObjectIdRef; import org.eclipse.jgit.lib.ObjectIdRef;
import org.eclipse.jgit.lib.ObjectInserter; import org.eclipse.jgit.lib.ObjectInserter;
* for processing. * for processing.
*/ */
public class Command { 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 oldRef;
private final Ref newRef; private final Ref newRef;
private final ReceiveCommand cmd; private final ReceiveCommand cmd;

+ 6
- 17
org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/reftree/RefTree.java View File

import static org.eclipse.jgit.lib.Ref.Storage.PACKED; 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.lib.RefDatabase.MAX_SYMBOLIC_REF_DEPTH;
import static org.eclipse.jgit.transport.ReceiveCommand.Result.LOCK_FAILURE; 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 static org.eclipse.jgit.transport.ReceiveCommand.Result.REJECTED_OTHER_REASON;


import java.io.IOException; import java.io.IOException;
if (!isValidRef(cmd)) { if (!isValidRef(cmd)) {
cmd.setResult(REJECTED_OTHER_REASON, cmd.setResult(REJECTED_OTHER_REASON,
JGitText.get().funnyRefname); JGitText.get().funnyRefname);
return abort(cmdList);
Command.abort(cmdList, null);
return false;
} }
apply(ed, cmd); apply(ed, cmd);
} }
break; break;
} }
} }
return abort(cmdList);
Command.abort(cmdList, null);
return false;
} catch (LockFailureException e) { } catch (LockFailureException e) {
return abort(cmdList);
Command.abort(cmdList, null);
return false;
} }
} }


} }
} }


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. * Convert a path name in a RefTree to the reference name known by Git.
* *

+ 4
- 22
org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/reftree/RefTreeBatch.java View File

} }
if (c.getType() == UPDATE_NONFASTFORWARD) { if (c.getType() == UPDATE_NONFASTFORWARD) {
c.setResult(REJECTED_NONFASTFORWARD); c.setResult(REJECTED_NONFASTFORWARD);
reject();
ReceiveCommand.abort(getCommands());
return; return;
} }
} }
execute(rw, todo); 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 { void init(RevWalk rw) throws IOException {
src = refdb.getBootstrap().exactRef(refdb.getTxnCommitted()); src = refdb.getBootstrap().exactRef(refdb.getTxnCommitted());
if (src != null && src.getObjectId() != null) { if (src != null && src.getObjectId() != null) {
void execute(RevWalk rw, List<Command> todo) throws IOException { void execute(RevWalk rw, List<Command> todo) throws IOException {
for (Command c : todo) { for (Command c : todo) {
if (c.getResult() != NOT_ATTEMPTED) { if (c.getResult() != NOT_ATTEMPTED) {
reject(todo, JGitText.get().transactionAborted);
Command.abort(todo, null);
return; return;
} }
if (refdb.conflictsWithBootstrap(c.getRefName())) { if (refdb.conflictsWithBootstrap(c.getRefName())) {
c.setResult(REJECTED_OTHER_REASON, MessageFormat c.setResult(REJECTED_OTHER_REASON, MessageFormat
.format(JGitText.get().invalidRefName, c.getRefName())); .format(JGitText.get().invalidRefName, c.getRefName()));
reject(todo, JGitText.get().transactionAborted);
Command.abort(todo, null);
return; return;
} }
} }
c.setResult(OK); c.setResult(OK);
} }
} else { } else {
reject(todo, commit.getResult().name());
Command.abort(todo, commit.getResult().name());
} }
} }


u.addCommand(commit); u.addCommand(commit);
u.execute(rw, NullProgressMonitor.INSTANCE); 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;
}
}
}
} }

+ 1
- 4
org.eclipse.jgit/src/org/eclipse/jgit/transport/BaseReceivePack.java View File

* @since 3.6 * @since 3.6
*/ */
protected void failPendingCommands() { 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);
} }


/** /**

+ 22
- 0
org.eclipse.jgit/src/org/eclipse/jgit/transport/ReceiveCommand.java View File



package org.eclipse.jgit.transport; 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.io.IOException;
import java.text.MessageFormat; import java.text.MessageFormat;
import java.util.ArrayList; import java.util.ArrayList;
return filter((Iterable<ReceiveCommand>) commands, want); 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 oldId;


private final ObjectId newId; private final ObjectId newId;

Loading…
Cancel
Save