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;
}
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;
}
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();
}
}
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;
}
}
}
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;
}
Aggregations