use of org.eclipse.jgit.transport.ReceiveCommand in project gerrit by GerritCodeReview.
the class NoteDbUpdateManager method checkResults.
/**
* Check results of all commands in the update batch, reducing to a single exception if there was
* a failure.
*
* <p>Throws {@link LockFailureException} if at least one command failed with {@code
* LOCK_FAILURE}, and the entire transaction was aborted, i.e. any non-{@code LOCK_FAILURE}
* results, if there were any, failed with "transaction aborted".
*
* <p>In particular, if the underlying ref database does not {@link
* org.eclipse.jgit.lib.RefDatabase#performsAtomicTransactions() perform atomic transactions},
* then a combination of {@code LOCK_FAILURE} on one ref and {@code OK} or another result on other
* refs will <em>not</em> throw {@code LockFailureException}.
*
* @param bru batch update; should already have been executed.
* @throws LockFailureException if the transaction was aborted due to lock failure.
* @throws IOException if any result was not {@code OK}.
*/
@VisibleForTesting
static void checkResults(BatchRefUpdate bru) throws LockFailureException, IOException {
int lockFailure = 0;
int aborted = 0;
int failure = 0;
for (ReceiveCommand cmd : bru.getCommands()) {
if (cmd.getResult() != ReceiveCommand.Result.OK) {
failure++;
}
if (cmd.getResult() == ReceiveCommand.Result.LOCK_FAILURE) {
lockFailure++;
} else if (cmd.getResult() == ReceiveCommand.Result.REJECTED_OTHER_REASON && JGitText.get().transactionAborted.equals(cmd.getMessage())) {
aborted++;
}
}
if (lockFailure + aborted == bru.getCommands().size()) {
throw new LockFailureException("Update aborted with one or more lock failures: " + bru);
} else if (failure > 0) {
throw new IOException("Update failed: " + bru);
}
}
use of org.eclipse.jgit.transport.ReceiveCommand in project gerrit by GerritCodeReview.
the class NoteDbUpdateManager method stage.
/**
* Stage updates in the manager's internal list of commands.
*
* @return map of the state that would get written to the applicable repo(s) for each affected
* change.
* @throws OrmException if a database layer error occurs.
* @throws IOException if a storage layer error occurs.
*/
public Map<Change.Id, StagedResult> stage() throws OrmException, IOException {
if (staged != null) {
return staged;
}
try (Timer1.Context timer = metrics.stageUpdateLatency.start(CHANGES)) {
staged = new HashMap<>();
if (isEmpty()) {
return staged;
}
initChangeRepo();
if (!draftUpdates.isEmpty() || !toDelete.isEmpty()) {
initAllUsersRepo();
}
checkExpectedState();
addCommands();
Table<Change.Id, Account.Id, ObjectId> allDraftIds = getDraftIds();
Set<Change.Id> changeIds = new HashSet<>();
for (ReceiveCommand cmd : changeRepo.getCommandsSnapshot()) {
Change.Id changeId = Change.Id.fromRef(cmd.getRefName());
if (changeId == null || !cmd.getRefName().equals(RefNames.changeMetaRef(changeId))) {
// Not a meta ref update, likely due to a repo update along with the change meta update.
continue;
}
changeIds.add(changeId);
Optional<ObjectId> metaId = Optional.of(cmd.getNewId());
staged.put(changeId, StagedResult.create(changeId, NoteDbChangeState.Delta.create(changeId, metaId, allDraftIds.rowMap().remove(changeId)), changeRepo, allUsersRepo));
}
for (Map.Entry<Change.Id, Map<Account.Id, ObjectId>> e : allDraftIds.rowMap().entrySet()) {
// If a change remains in the table at this point, it means we are
// updating its drafts but not the change itself.
StagedResult r = StagedResult.create(e.getKey(), NoteDbChangeState.Delta.create(e.getKey(), Optional.empty(), e.getValue()), changeRepo, allUsersRepo);
checkState(r.changeCommands().isEmpty(), "should not have change commands when updating only drafts: %s", r);
staged.put(r.id(), r);
}
return staged;
}
}
use of org.eclipse.jgit.transport.ReceiveCommand in project gerrit by GerritCodeReview.
the class ChangeRebuilderImpl method deleteChangeMetaRef.
private void deleteChangeMetaRef(Change change, ChainedReceiveCommands cmds) throws IOException {
String refName = changeMetaRef(change.getId());
Optional<ObjectId> old = cmds.get(refName);
if (old.isPresent()) {
cmds.add(new ReceiveCommand(old.get(), ObjectId.zeroId(), refName));
}
}
use of org.eclipse.jgit.transport.ReceiveCommand in project gerrit by GerritCodeReview.
the class ChangeEditModifier method updateReferenceWithNameChange.
private void updateReferenceWithNameChange(Repository repository, String currentRefName, ObjectId currentObjectId, String newRefName, ObjectId targetObjectId, Timestamp timestamp) throws IOException {
BatchRefUpdate batchRefUpdate = repository.getRefDatabase().newBatchUpdate();
batchRefUpdate.addCommand(new ReceiveCommand(ObjectId.zeroId(), targetObjectId, newRefName));
batchRefUpdate.addCommand(new ReceiveCommand(currentObjectId, ObjectId.zeroId(), currentRefName));
batchRefUpdate.setRefLogMessage("rebase edit", false);
batchRefUpdate.setRefLogIdent(getRefLogIdent(timestamp));
try (RevWalk revWalk = new RevWalk(repository)) {
batchRefUpdate.execute(revWalk, NullProgressMonitor.INSTANCE);
}
for (ReceiveCommand cmd : batchRefUpdate.getCommands()) {
if (cmd.getResult() != ReceiveCommand.Result.OK) {
throw new IOException("failed: " + cmd);
}
}
}
use of org.eclipse.jgit.transport.ReceiveCommand in project gerrit by GerritCodeReview.
the class DeleteRef method deleteMultipleRefs.
private void deleteMultipleRefs(Repository r) throws OrmException, IOException, ResourceConflictException, PermissionBackendException {
BatchRefUpdate batchUpdate = r.getRefDatabase().newBatchUpdate();
batchUpdate.setAtomic(false);
List<String> refs = prefix == null ? refsToDelete : refsToDelete.stream().map(ref -> ref.startsWith(prefix) ? ref : prefix + ref).collect(toList());
for (String ref : refs) {
batchUpdate.addCommand(createDeleteCommand(resource, r, ref));
}
try (RevWalk rw = new RevWalk(r)) {
batchUpdate.execute(rw, NullProgressMonitor.INSTANCE);
}
StringBuilder errorMessages = new StringBuilder();
for (ReceiveCommand command : batchUpdate.getCommands()) {
if (command.getResult() == Result.OK) {
postDeletion(resource, command);
} else {
appendAndLogErrorMessage(errorMessages, command);
}
}
if (errorMessages.length() > 0) {
throw new ResourceConflictException(errorMessages.toString());
}
}
Aggregations