Search in sources :

Example 1 with ConcurrentRefUpdateException

use of org.eclipse.jgit.api.errors.ConcurrentRefUpdateException in project gitblit by gitblit.

the class RefLogUtils method updateRefLog.

/**
	 * Updates the reflog with the received commands.
	 *
	 * @param user
	 * @param repository
	 * @param commands
	 * @return true, if the update was successful
	 */
public static boolean updateRefLog(UserModel user, Repository repository, Collection<ReceiveCommand> commands) {
    // only track branches and tags
    List<ReceiveCommand> filteredCommands = new ArrayList<ReceiveCommand>();
    for (ReceiveCommand cmd : commands) {
        if (!cmd.getRefName().startsWith(Constants.R_HEADS) && !cmd.getRefName().startsWith(Constants.R_TAGS)) {
            continue;
        }
        filteredCommands.add(cmd);
    }
    if (filteredCommands.isEmpty()) {
        // nothing to log
        return true;
    }
    RefModel reflogBranch = getRefLogBranch(repository);
    if (reflogBranch == null) {
        JGitUtils.createOrphanBranch(repository, GB_REFLOG, null);
    }
    boolean success = false;
    String message = "push";
    try {
        ObjectId headId = repository.resolve(GB_REFLOG + "^{commit}");
        ObjectInserter odi = repository.newObjectInserter();
        try {
            // Create the in-memory index of the reflog log entry
            DirCache index = createIndex(repository, headId, commands);
            ObjectId indexTreeId = index.writeTree(odi);
            PersonIdent ident;
            if (UserModel.ANONYMOUS.equals(user)) {
                // anonymous push
                ident = new PersonIdent(user.username + "/" + user.username, user.username);
            } else {
                // construct real pushing account
                ident = new PersonIdent(MessageFormat.format("{0}/{1}", user.getDisplayName(), user.username), user.emailAddress == null ? user.username : user.emailAddress);
            }
            // Create a commit object
            CommitBuilder commit = new CommitBuilder();
            commit.setAuthor(ident);
            commit.setCommitter(ident);
            commit.setEncoding(Constants.ENCODING);
            commit.setMessage(message);
            commit.setParentId(headId);
            commit.setTreeId(indexTreeId);
            // Insert the commit into the repository
            ObjectId commitId = odi.insert(commit);
            odi.flush();
            RevWalk revWalk = new RevWalk(repository);
            try {
                RevCommit revCommit = revWalk.parseCommit(commitId);
                RefUpdate ru = repository.updateRef(GB_REFLOG);
                ru.setNewObjectId(commitId);
                ru.setExpectedOldObjectId(headId);
                ru.setRefLogMessage("commit: " + revCommit.getShortMessage(), false);
                Result rc = ru.forceUpdate();
                switch(rc) {
                    case NEW:
                    case FORCED:
                    case FAST_FORWARD:
                        success = true;
                        break;
                    case REJECTED:
                    case LOCK_FAILURE:
                        throw new ConcurrentRefUpdateException(JGitText.get().couldNotLockHEAD, ru.getRef(), rc);
                    default:
                        throw new JGitInternalException(MessageFormat.format(JGitText.get().updatingRefFailed, GB_REFLOG, commitId.toString(), rc));
                }
            } finally {
                revWalk.close();
            }
        } finally {
            odi.close();
        }
    } catch (Throwable t) {
        error(t, repository, "Failed to commit reflog entry to {0}");
    }
    return success;
}
Also used : ReceiveCommand(org.eclipse.jgit.transport.ReceiveCommand) RefModel(com.gitblit.models.RefModel) ObjectId(org.eclipse.jgit.lib.ObjectId) ArrayList(java.util.ArrayList) CommitBuilder(org.eclipse.jgit.lib.CommitBuilder) RevWalk(org.eclipse.jgit.revwalk.RevWalk) Result(org.eclipse.jgit.lib.RefUpdate.Result) DirCache(org.eclipse.jgit.dircache.DirCache) ObjectInserter(org.eclipse.jgit.lib.ObjectInserter) PersonIdent(org.eclipse.jgit.lib.PersonIdent) JGitInternalException(org.eclipse.jgit.api.errors.JGitInternalException) ConcurrentRefUpdateException(org.eclipse.jgit.api.errors.ConcurrentRefUpdateException) RevCommit(org.eclipse.jgit.revwalk.RevCommit) RefUpdate(org.eclipse.jgit.lib.RefUpdate)

Example 2 with ConcurrentRefUpdateException

use of org.eclipse.jgit.api.errors.ConcurrentRefUpdateException in project gitblit by gitblit.

the class JGitUtils method commitIndex.

public static boolean commitIndex(Repository db, String branch, DirCache index, ObjectId parentId, boolean forceCommit, String author, String authorEmail, String message) throws IOException, ConcurrentRefUpdateException {
    boolean success = false;
    ObjectId headId = db.resolve(branch + "^{commit}");
    ObjectId baseId = parentId;
    if (baseId == null || headId == null) {
        return false;
    }
    ObjectInserter odi = db.newObjectInserter();
    try {
        // Create the in-memory index of the new/updated ticket
        ObjectId indexTreeId = index.writeTree(odi);
        // Create a commit object
        PersonIdent ident = new PersonIdent(author, authorEmail);
        if (forceCommit == false) {
            ThreeWayMerger merger = MergeStrategy.RECURSIVE.newMerger(db, true);
            merger.setObjectInserter(odi);
            merger.setBase(baseId);
            boolean mergeSuccess = merger.merge(indexTreeId, headId);
            if (mergeSuccess) {
                indexTreeId = merger.getResultTreeId();
            } else {
                //Manual merge required
                return false;
            }
        }
        CommitBuilder commit = new CommitBuilder();
        commit.setAuthor(ident);
        commit.setCommitter(ident);
        commit.setEncoding(com.gitblit.Constants.ENCODING);
        commit.setMessage(message);
        commit.setParentId(headId);
        commit.setTreeId(indexTreeId);
        // Insert the commit into the repository
        ObjectId commitId = odi.insert(commit);
        odi.flush();
        RevWalk revWalk = new RevWalk(db);
        try {
            RevCommit revCommit = revWalk.parseCommit(commitId);
            RefUpdate ru = db.updateRef(branch);
            ru.setForceUpdate(forceCommit);
            ru.setNewObjectId(commitId);
            ru.setExpectedOldObjectId(headId);
            ru.setRefLogMessage("commit: " + revCommit.getShortMessage(), false);
            Result rc = ru.update();
            switch(rc) {
                case NEW:
                case FORCED:
                case FAST_FORWARD:
                    success = true;
                    break;
                case REJECTED:
                case LOCK_FAILURE:
                    throw new ConcurrentRefUpdateException(JGitText.get().couldNotLockHEAD, ru.getRef(), rc);
                default:
                    throw new JGitInternalException(MessageFormat.format(JGitText.get().updatingRefFailed, branch, commitId.toString(), rc));
            }
        } finally {
            revWalk.close();
        }
    } finally {
        odi.close();
    }
    return success;
}
Also used : ObjectInserter(org.eclipse.jgit.lib.ObjectInserter) AnyObjectId(org.eclipse.jgit.lib.AnyObjectId) ObjectId(org.eclipse.jgit.lib.ObjectId) PersonIdent(org.eclipse.jgit.lib.PersonIdent) CommitBuilder(org.eclipse.jgit.lib.CommitBuilder) JGitInternalException(org.eclipse.jgit.api.errors.JGitInternalException) ThreeWayMerger(org.eclipse.jgit.merge.ThreeWayMerger) RevWalk(org.eclipse.jgit.revwalk.RevWalk) ConcurrentRefUpdateException(org.eclipse.jgit.api.errors.ConcurrentRefUpdateException) RevCommit(org.eclipse.jgit.revwalk.RevCommit) RefUpdate(org.eclipse.jgit.lib.RefUpdate) FetchResult(org.eclipse.jgit.transport.FetchResult) Result(org.eclipse.jgit.lib.RefUpdate.Result)

Example 3 with ConcurrentRefUpdateException

use of org.eclipse.jgit.api.errors.ConcurrentRefUpdateException in project gitblit by gitblit.

the class BranchTicketService method writeTicketsFile.

/**
	 * Writes a file to the tickets branch.
	 *
	 * @param db
	 * @param file
	 * @param content
	 * @param createdBy
	 * @param msg
	 */
private void writeTicketsFile(Repository db, String file, String content, String createdBy, String msg) {
    if (getTicketsBranch(db) == null) {
        createTicketsBranch(db);
    }
    DirCache newIndex = DirCache.newInCore();
    DirCacheBuilder builder = newIndex.builder();
    ObjectInserter inserter = db.newObjectInserter();
    try {
        // create an index entry for the revised index
        final DirCacheEntry idIndexEntry = new DirCacheEntry(file);
        idIndexEntry.setLength(content.length());
        idIndexEntry.setLastModified(System.currentTimeMillis());
        idIndexEntry.setFileMode(FileMode.REGULAR_FILE);
        // insert new ticket index
        idIndexEntry.setObjectId(inserter.insert(org.eclipse.jgit.lib.Constants.OBJ_BLOB, content.getBytes(Constants.ENCODING)));
        // add to temporary in-core index
        builder.add(idIndexEntry);
        Set<String> ignorePaths = new HashSet<String>();
        ignorePaths.add(file);
        for (DirCacheEntry entry : JGitUtils.getTreeEntries(db, BRANCH, ignorePaths)) {
            builder.add(entry);
        }
        // finish temporary in-core index used for this commit
        builder.finish();
        // commit the change
        commitIndex(db, newIndex, createdBy, msg);
    } catch (ConcurrentRefUpdateException e) {
        log.error("", e);
    } catch (IOException e) {
        log.error("", e);
    } finally {
        inserter.close();
    }
}
Also used : DirCache(org.eclipse.jgit.dircache.DirCache) DirCacheBuilder(org.eclipse.jgit.dircache.DirCacheBuilder) DirCacheEntry(org.eclipse.jgit.dircache.DirCacheEntry) ObjectInserter(org.eclipse.jgit.lib.ObjectInserter) IOException(java.io.IOException) ConcurrentRefUpdateException(org.eclipse.jgit.api.errors.ConcurrentRefUpdateException) HashSet(java.util.HashSet)

Example 4 with ConcurrentRefUpdateException

use of org.eclipse.jgit.api.errors.ConcurrentRefUpdateException in project gerrit by GerritCodeReview.

the class NotesBranchUtil method updateRef.

private void updateRef(String notesBranch) throws IOException, MissingObjectException, IncorrectObjectTypeException, CorruptObjectException, ConcurrentRefUpdateException {
    if (baseCommit != null && oursCommit.getTree().equals(baseCommit.getTree())) {
        // Avoid saving this commit as it has no new information.
        return;
    }
    int remainingLockFailureCalls = MAX_LOCK_FAILURE_CALLS;
    RefUpdate refUpdate = createRefUpdate(notesBranch, oursCommit, baseCommit);
    for (; ; ) {
        Result result = refUpdate.update();
        if (result == Result.LOCK_FAILURE) {
            if (--remainingLockFailureCalls > 0) {
                try {
                    Thread.sleep(SLEEP_ON_LOCK_FAILURE_MS);
                } catch (InterruptedException e) {
                // ignore
                }
            } else {
                throw new ConcurrentRefUpdateException("Failed to lock the ref: " + notesBranch, refUpdate.getRef(), result);
            }
        } else if (result == Result.REJECTED) {
            RevCommit theirsCommit = revWalk.parseCommit(refUpdate.getOldObjectId());
            NoteMap theirs = NoteMap.read(revWalk.getObjectReader(), theirsCommit);
            NoteMapMerger merger = new NoteMapMerger(db, getNoteMerger(), MergeStrategy.RESOLVE);
            NoteMap merged = merger.merge(base, ours, theirs);
            RevCommit mergeCommit = createCommit(merged, gerritIdent, "Merged note commits\n", theirsCommit, oursCommit);
            refUpdate = createRefUpdate(notesBranch, mergeCommit, theirsCommit);
            remainingLockFailureCalls = MAX_LOCK_FAILURE_CALLS;
        } else if (result == Result.IO_FAILURE) {
            throw new IOException("Couldn't update " + notesBranch + ". " + result.name());
        } else {
            gitRefUpdated.fire(project, refUpdate, null);
            break;
        }
    }
}
Also used : NoteMap(org.eclipse.jgit.notes.NoteMap) IOException(java.io.IOException) ConcurrentRefUpdateException(org.eclipse.jgit.api.errors.ConcurrentRefUpdateException) NoteMapMerger(org.eclipse.jgit.notes.NoteMapMerger) RefUpdate(org.eclipse.jgit.lib.RefUpdate) Result(org.eclipse.jgit.lib.RefUpdate.Result) RevCommit(org.eclipse.jgit.revwalk.RevCommit)

Example 5 with ConcurrentRefUpdateException

use of org.eclipse.jgit.api.errors.ConcurrentRefUpdateException in project gerrit by GerritCodeReview.

the class BanCommit method apply.

@Override
public BanResultInfo apply(ProjectResource rsrc, Input input) throws UnprocessableEntityException, AuthException, ResourceConflictException, IOException {
    BanResultInfo r = new BanResultInfo();
    if (input != null && input.commits != null && !input.commits.isEmpty()) {
        List<ObjectId> commitsToBan = new ArrayList<>(input.commits.size());
        for (String c : input.commits) {
            try {
                commitsToBan.add(ObjectId.fromString(c));
            } catch (IllegalArgumentException e) {
                throw new UnprocessableEntityException(e.getMessage());
            }
        }
        try {
            BanCommitResult result = banCommit.ban(rsrc.getControl(), commitsToBan, input.reason);
            r.newlyBanned = transformCommits(result.getNewlyBannedCommits());
            r.alreadyBanned = transformCommits(result.getAlreadyBannedCommits());
            r.ignored = transformCommits(result.getIgnoredObjectIds());
        } catch (PermissionDeniedException e) {
            throw new AuthException(e.getMessage());
        } catch (ConcurrentRefUpdateException e) {
            throw new ResourceConflictException(e.getMessage(), e);
        }
    }
    return r;
}
Also used : UnprocessableEntityException(com.google.gerrit.extensions.restapi.UnprocessableEntityException) ResourceConflictException(com.google.gerrit.extensions.restapi.ResourceConflictException) ObjectId(org.eclipse.jgit.lib.ObjectId) ArrayList(java.util.ArrayList) AuthException(com.google.gerrit.extensions.restapi.AuthException) PermissionDeniedException(com.google.gerrit.common.errors.PermissionDeniedException) BanCommitResult(com.google.gerrit.server.git.BanCommitResult) ConcurrentRefUpdateException(org.eclipse.jgit.api.errors.ConcurrentRefUpdateException)

Aggregations

ConcurrentRefUpdateException (org.eclipse.jgit.api.errors.ConcurrentRefUpdateException)5 ObjectId (org.eclipse.jgit.lib.ObjectId)3 ObjectInserter (org.eclipse.jgit.lib.ObjectInserter)3 RefUpdate (org.eclipse.jgit.lib.RefUpdate)3 Result (org.eclipse.jgit.lib.RefUpdate.Result)3 RevCommit (org.eclipse.jgit.revwalk.RevCommit)3 IOException (java.io.IOException)2 ArrayList (java.util.ArrayList)2 JGitInternalException (org.eclipse.jgit.api.errors.JGitInternalException)2 DirCache (org.eclipse.jgit.dircache.DirCache)2 CommitBuilder (org.eclipse.jgit.lib.CommitBuilder)2 PersonIdent (org.eclipse.jgit.lib.PersonIdent)2 RevWalk (org.eclipse.jgit.revwalk.RevWalk)2 RefModel (com.gitblit.models.RefModel)1 PermissionDeniedException (com.google.gerrit.common.errors.PermissionDeniedException)1 AuthException (com.google.gerrit.extensions.restapi.AuthException)1 ResourceConflictException (com.google.gerrit.extensions.restapi.ResourceConflictException)1 UnprocessableEntityException (com.google.gerrit.extensions.restapi.UnprocessableEntityException)1 BanCommitResult (com.google.gerrit.server.git.BanCommitResult)1 HashSet (java.util.HashSet)1