Search in sources :

Example 1 with GitUpdateFailureException

use of com.google.gerrit.git.GitUpdateFailureException in project gerrit by GerritCodeReview.

the class StarredChangesUtil method unstarAllForChangeDeletion.

/**
 * Unstar the given change for all users.
 *
 * <p>Intended for use only when we're about to delete a change. For that reason, the change is
 * not reindexed.
 *
 * @param changeId change ID.
 * @throws IOException if an error occurred.
 */
public void unstarAllForChangeDeletion(Change.Id changeId) throws IOException {
    try (Repository repo = repoManager.openRepository(allUsers);
        RevWalk rw = new RevWalk(repo)) {
        BatchRefUpdate batchUpdate = repo.getRefDatabase().newBatchUpdate();
        batchUpdate.setAllowNonFastForwards(true);
        batchUpdate.setRefLogIdent(serverIdent.get());
        batchUpdate.setRefLogMessage("Unstar change " + changeId.get(), true);
        for (Account.Id accountId : byChangeFromIndex(changeId).keySet()) {
            String refName = RefNames.refsStarredChanges(changeId, accountId);
            Ref ref = repo.getRefDatabase().exactRef(refName);
            if (ref != null) {
                batchUpdate.addCommand(new ReceiveCommand(ref.getObjectId(), ObjectId.zeroId(), refName));
            }
        }
        batchUpdate.execute(rw, NullProgressMonitor.INSTANCE);
        for (ReceiveCommand command : batchUpdate.getCommands()) {
            if (command.getResult() != ReceiveCommand.Result.OK) {
                String message = String.format("Unstar change %d failed, ref %s could not be deleted: %s", changeId.get(), command.getRefName(), command.getResult());
                if (command.getResult() == ReceiveCommand.Result.LOCK_FAILURE) {
                    throw new LockFailureException(message, batchUpdate);
                }
                throw new GitUpdateFailureException(message, batchUpdate);
            }
        }
    }
}
Also used : Account(com.google.gerrit.entities.Account) ReceiveCommand(org.eclipse.jgit.transport.ReceiveCommand) Repository(org.eclipse.jgit.lib.Repository) Ref(org.eclipse.jgit.lib.Ref) GitUpdateFailureException(com.google.gerrit.git.GitUpdateFailureException) RevWalk(org.eclipse.jgit.revwalk.RevWalk) BatchRefUpdate(org.eclipse.jgit.lib.BatchRefUpdate) LockFailureException(com.google.gerrit.git.LockFailureException)

Example 2 with GitUpdateFailureException

use of com.google.gerrit.git.GitUpdateFailureException in project gerrit by GerritCodeReview.

the class VersionedMetaData method openUpdate.

/**
 * Open a batch of updates to the same metadata ref.
 *
 * <p>This allows making multiple commits to a single metadata ref, at the end of which is a
 * single ref update. For batching together updates to multiple refs (each consisting of one or
 * more commits against their respective refs), create the {@link MetaDataUpdate} with a {@link
 * BatchRefUpdate}.
 *
 * <p>A ref update produced by this {@link BatchMetaDataUpdate} is only committed if there is no
 * associated {@link BatchRefUpdate}. As a result, the configured ref updated event is not fired
 * if there is an associated batch.
 *
 * <p>If object inserter, reader and revwalk are provided, then the updates are not flushed,
 * allowing callers the flexibility to flush only once after several updates.
 *
 * @param update helper info about the update.
 * @param objInserter Shared object inserter.
 * @param objReader Shared object reader.
 * @param revWalk Shared rev walk.
 * @throws IOException if the update failed.
 */
public BatchMetaDataUpdate openUpdate(MetaDataUpdate update, ObjectInserter objInserter, ObjectReader objReader, RevWalk revWalk) throws IOException {
    final Repository db = update.getRepository();
    inserter = objInserter == null ? db.newObjectInserter() : objInserter;
    reader = objReader == null ? inserter.newReader() : objReader;
    final RevWalk rw = revWalk == null ? new RevWalk(reader) : revWalk;
    final RevTree tree = revision != null ? rw.parseTree(revision) : null;
    newTree = readTree(tree);
    return new BatchMetaDataUpdate() {

        RevCommit src = revision;

        AnyObjectId srcTree = tree;

        @Override
        public void write(CommitBuilder commit) throws IOException {
            write(VersionedMetaData.this, commit);
        }

        private boolean doSave(VersionedMetaData config, CommitBuilder commit) throws IOException {
            DirCache nt = config.newTree;
            ObjectReader r = config.reader;
            ObjectInserter i = config.inserter;
            RevCommit c = config.revision;
            try {
                config.newTree = newTree;
                config.reader = reader;
                config.inserter = inserter;
                config.revision = src;
                return config.onSave(commit);
            } catch (ConfigInvalidException e) {
                throw new IOException("Cannot update " + getRefName() + " in " + db.getDirectory() + ": " + e.getMessage(), e);
            } finally {
                config.newTree = nt;
                config.reader = r;
                config.inserter = i;
                config.revision = c;
            }
        }

        @Override
        public void write(VersionedMetaData config, CommitBuilder commit) throws IOException {
            checkSameRef(config);
            if (!doSave(config, commit)) {
                return;
            }
            ObjectId res = newTree.writeTree(inserter);
            if (res.equals(srcTree) && !update.allowEmpty() && (commit.getTreeId() == null)) {
                // If there are no changes to the content, don't create the commit.
                return;
            }
            // the tree for the updated DirCache.
            if (commit.getTreeId() == null) {
                commit.setTreeId(res);
            } else {
                // In this case, the caller populated the tree without using DirCache.
                res = commit.getTreeId();
            }
            if (src != null) {
                commit.addParentId(src);
            }
            if (update.insertChangeId()) {
                commit.setMessage(ChangeIdUtil.insertId(commit.getMessage(), CommitMessageUtil.generateChangeId()));
            }
            src = rw.parseCommit(inserter.insert(commit));
            srcTree = res;
        }

        private void checkSameRef(VersionedMetaData other) {
            String thisRef = VersionedMetaData.this.getRefName();
            String otherRef = other.getRefName();
            checkArgument(otherRef.equals(thisRef), "cannot add %s for %s to %s on %s", other.getClass().getSimpleName(), otherRef, BatchMetaDataUpdate.class.getSimpleName(), thisRef);
        }

        @Override
        public RevCommit createRef(String refName) throws IOException {
            if (Objects.equals(src, revision)) {
                return revision;
            }
            return updateRef(ObjectId.zeroId(), src, refName);
        }

        @Override
        public RevCommit commit() throws IOException {
            return commitAt(revision);
        }

        @Override
        public RevCommit commitAt(ObjectId expected) throws IOException {
            if (Objects.equals(src, expected)) {
                return revision;
            }
            return updateRef(MoreObjects.firstNonNull(expected, ObjectId.zeroId()), src, getRefName());
        }

        @Override
        public void close() {
            newTree = null;
            if (revWalk == null) {
                rw.close();
            }
            if (objInserter == null && inserter != null) {
                inserter.close();
                inserter = null;
            }
            if (objReader == null && reader != null) {
                reader.close();
                reader = null;
            }
        }

        private RevCommit updateRef(AnyObjectId oldId, AnyObjectId newId, String refName) throws IOException {
            BatchRefUpdate bru = update.getBatch();
            if (bru != null) {
                bru.addCommand(new ReceiveCommand(oldId.toObjectId(), newId.toObjectId(), refName));
                if (objInserter == null) {
                    inserter.flush();
                }
                revision = rw.parseCommit(newId);
                return revision;
            }
            RefUpdate ru = db.updateRef(refName);
            ru.setExpectedOldObjectId(oldId);
            ru.setNewObjectId(newId);
            ru.setRefLogIdent(update.getCommitBuilder().getAuthor());
            String message = update.getCommitBuilder().getMessage();
            if (message == null) {
                message = "meta data update";
            }
            try (BufferedReader reader = new BufferedReader(new StringReader(message))) {
                // read the subject line and use it as reflog message
                ru.setRefLogMessage("commit: " + reader.readLine(), true);
            }
            logger.atFine().log("Saving commit '%s' on project '%s'", message.trim(), projectName);
            inserter.flush();
            RefUpdate.Result result = ru.update();
            switch(result) {
                case NEW:
                case FAST_FORWARD:
                    revision = rw.parseCommit(ru.getNewObjectId());
                    update.fireGitRefUpdatedEvent(ru);
                    logger.atFine().log("Saved commit '%s' as revision '%s' on project '%s'", message.trim(), revision.name(), projectName);
                    return revision;
                case LOCK_FAILURE:
                    throw new LockFailureException(errorMsg(ru, db.getDirectory()), ru);
                case FORCED:
                case IO_FAILURE:
                case NOT_ATTEMPTED:
                case NO_CHANGE:
                case REJECTED:
                case REJECTED_CURRENT_BRANCH:
                case RENAMED:
                case REJECTED_MISSING_OBJECT:
                case REJECTED_OTHER_REASON:
                default:
                    throw new GitUpdateFailureException(errorMsg(ru, db.getDirectory()), ru);
            }
        }
    };
}
Also used : ReceiveCommand(org.eclipse.jgit.transport.ReceiveCommand) GitUpdateFailureException(com.google.gerrit.git.GitUpdateFailureException) ConfigInvalidException(org.eclipse.jgit.errors.ConfigInvalidException) AnyObjectId(org.eclipse.jgit.lib.AnyObjectId) ObjectId(org.eclipse.jgit.lib.ObjectId) CommitBuilder(org.eclipse.jgit.lib.CommitBuilder) IOException(java.io.IOException) RevWalk(org.eclipse.jgit.revwalk.RevWalk) LockFailureException(com.google.gerrit.git.LockFailureException) AnyObjectId(org.eclipse.jgit.lib.AnyObjectId) DirCache(org.eclipse.jgit.dircache.DirCache) Repository(org.eclipse.jgit.lib.Repository) ObjectInserter(org.eclipse.jgit.lib.ObjectInserter) BufferedReader(java.io.BufferedReader) StringReader(java.io.StringReader) ObjectReader(org.eclipse.jgit.lib.ObjectReader) RevTree(org.eclipse.jgit.revwalk.RevTree) BatchRefUpdate(org.eclipse.jgit.lib.BatchRefUpdate) RevCommit(org.eclipse.jgit.revwalk.RevCommit) RefUpdate(org.eclipse.jgit.lib.RefUpdate) BatchRefUpdate(org.eclipse.jgit.lib.BatchRefUpdate)

Aggregations

GitUpdateFailureException (com.google.gerrit.git.GitUpdateFailureException)2 LockFailureException (com.google.gerrit.git.LockFailureException)2 BatchRefUpdate (org.eclipse.jgit.lib.BatchRefUpdate)2 Repository (org.eclipse.jgit.lib.Repository)2 RevWalk (org.eclipse.jgit.revwalk.RevWalk)2 ReceiveCommand (org.eclipse.jgit.transport.ReceiveCommand)2 Account (com.google.gerrit.entities.Account)1 BufferedReader (java.io.BufferedReader)1 IOException (java.io.IOException)1 StringReader (java.io.StringReader)1 DirCache (org.eclipse.jgit.dircache.DirCache)1 ConfigInvalidException (org.eclipse.jgit.errors.ConfigInvalidException)1 AnyObjectId (org.eclipse.jgit.lib.AnyObjectId)1 CommitBuilder (org.eclipse.jgit.lib.CommitBuilder)1 ObjectId (org.eclipse.jgit.lib.ObjectId)1 ObjectInserter (org.eclipse.jgit.lib.ObjectInserter)1 ObjectReader (org.eclipse.jgit.lib.ObjectReader)1 Ref (org.eclipse.jgit.lib.Ref)1 RefUpdate (org.eclipse.jgit.lib.RefUpdate)1 RevCommit (org.eclipse.jgit.revwalk.RevCommit)1