use of com.google.gerrit.extensions.restapi.MergeConflictException in project gerrit by GerritCodeReview.
the class MergeUtil method createCherryPickFromCommit.
public CodeReviewCommit createCherryPickFromCommit(ObjectInserter inserter, Config repoConfig, RevCommit mergeTip, RevCommit originalCommit, PersonIdent cherryPickCommitterIdent, String commitMsg, CodeReviewRevWalk rw, int parentIndex, boolean ignoreIdenticalTree) throws MissingObjectException, IncorrectObjectTypeException, IOException, MergeIdenticalTreeException, MergeConflictException {
final ThreeWayMerger m = newThreeWayMerger(inserter, repoConfig);
m.setBase(originalCommit.getParent(parentIndex));
if (m.merge(mergeTip, originalCommit)) {
ObjectId tree = m.getResultTreeId();
if (tree.equals(mergeTip.getTree()) && !ignoreIdenticalTree) {
throw new MergeIdenticalTreeException("identical tree");
}
CommitBuilder mergeCommit = new CommitBuilder();
mergeCommit.setTreeId(tree);
mergeCommit.setParentId(mergeTip);
mergeCommit.setAuthor(originalCommit.getAuthorIdent());
mergeCommit.setCommitter(cherryPickCommitterIdent);
mergeCommit.setMessage(commitMsg);
return rw.parseCommit(inserter.insert(mergeCommit));
}
throw new MergeConflictException("merge conflict");
}
use of com.google.gerrit.extensions.restapi.MergeConflictException in project gerrit by GerritCodeReview.
the class MergeUtil method createMergeCommit.
public static RevCommit createMergeCommit(ObjectInserter inserter, Config repoConfig, RevCommit mergeTip, RevCommit originalCommit, String mergeStrategy, PersonIdent committerIndent, String commitMsg, RevWalk rw) throws IOException, MergeIdenticalTreeException, MergeConflictException {
if (!MergeStrategy.THEIRS.getName().equals(mergeStrategy) && rw.isMergedInto(originalCommit, mergeTip)) {
throw new ChangeAlreadyMergedException("'" + originalCommit.getName() + "' has already been merged");
}
Merger m = newMerger(inserter, repoConfig, mergeStrategy);
if (m.merge(false, mergeTip, originalCommit)) {
ObjectId tree = m.getResultTreeId();
CommitBuilder mergeCommit = new CommitBuilder();
mergeCommit.setTreeId(tree);
mergeCommit.setParentIds(mergeTip, originalCommit);
mergeCommit.setAuthor(committerIndent);
mergeCommit.setCommitter(committerIndent);
mergeCommit.setMessage(commitMsg);
return rw.parseCommit(inserter.insert(mergeCommit));
}
List<String> conflicts = ImmutableList.of();
if (m instanceof ResolveMerger) {
conflicts = ((ResolveMerger) m).getUnmergedPaths();
}
throw new MergeConflictException(createConflictMessage(conflicts));
}
use of com.google.gerrit.extensions.restapi.MergeConflictException in project gerrit by GerritCodeReview.
the class ChangeEditModifier method merge.
private static ObjectId merge(Repository repository, ChangeEdit changeEdit, ObjectId newTreeId) throws IOException, MergeConflictException {
PatchSet basePatchSet = changeEdit.getBasePatchSet();
ObjectId basePatchSetCommitId = getPatchSetCommitId(basePatchSet);
ObjectId editCommitId = changeEdit.getEditCommit();
ThreeWayMerger threeWayMerger = MergeStrategy.RESOLVE.newMerger(repository, true);
threeWayMerger.setBase(basePatchSetCommitId);
boolean successful = threeWayMerger.merge(newTreeId, editCommitId);
if (!successful) {
throw new MergeConflictException("The existing change edit could not be merged with another tree.");
}
return threeWayMerger.getResultTreeId();
}
use of com.google.gerrit.extensions.restapi.MergeConflictException in project gerrit by GerritCodeReview.
the class CherryPickChange method cherryPick.
public Change.Id cherryPick(BatchUpdate.Factory batchUpdateFactory, @Nullable Change.Id sourceChangeId, @Nullable PatchSet.Id sourcePatchId, @Nullable Branch.NameKey sourceBranch, @Nullable String sourceChangeTopic, Project.NameKey project, ObjectId sourceCommit, CherryPickInput input, String targetRef, RefControl targetRefControl) throws OrmException, IOException, InvalidChangeOperationException, IntegrationException, UpdateException, RestApiException {
if (Strings.isNullOrEmpty(targetRef)) {
throw new InvalidChangeOperationException("Cherry Pick: Destination branch cannot be null or empty");
}
String destinationBranch = RefNames.shortName(targetRef);
IdentifiedUser identifiedUser = user.get();
try (Repository git = gitManager.openRepository(project);
// before patch sets are updated.
ObjectInserter oi = git.newObjectInserter();
ObjectReader reader = oi.newReader();
CodeReviewRevWalk revWalk = CodeReviewCommit.newRevWalk(reader)) {
Ref destRef = git.getRefDatabase().exactRef(targetRef);
if (destRef == null) {
throw new InvalidChangeOperationException(String.format("Branch %s does not exist.", destinationBranch));
}
CodeReviewCommit mergeTip = revWalk.parseCommit(destRef.getObjectId());
CodeReviewCommit commitToCherryPick = revWalk.parseCommit(sourceCommit);
if (input.parent <= 0 || input.parent > commitToCherryPick.getParentCount()) {
throw new InvalidChangeOperationException(String.format("Cherry Pick: Parent %s does not exist. Please specify a parent in" + " range [1, %s].", input.parent, commitToCherryPick.getParentCount()));
}
Timestamp now = TimeUtil.nowTs();
PersonIdent committerIdent = identifiedUser.newCommitterIdent(now, serverTimeZone);
final ObjectId computedChangeId = ChangeIdUtil.computeChangeId(commitToCherryPick.getTree(), mergeTip, commitToCherryPick.getAuthorIdent(), committerIdent, input.message);
String commitMessage = ChangeIdUtil.insertId(input.message, computedChangeId).trim() + '\n';
CodeReviewCommit cherryPickCommit;
try {
ProjectState projectState = targetRefControl.getProjectControl().getProjectState();
cherryPickCommit = mergeUtilFactory.create(projectState).createCherryPickFromCommit(oi, git.getConfig(), mergeTip, commitToCherryPick, committerIdent, commitMessage, revWalk, input.parent - 1, false);
Change.Key changeKey;
final List<String> idList = cherryPickCommit.getFooterLines(FooterConstants.CHANGE_ID);
if (!idList.isEmpty()) {
final String idStr = idList.get(idList.size() - 1).trim();
changeKey = new Change.Key(idStr);
} else {
changeKey = new Change.Key("I" + computedChangeId.name());
}
Branch.NameKey newDest = new Branch.NameKey(project, destRef.getName());
List<ChangeData> destChanges = queryProvider.get().setLimit(2).byBranchKey(newDest, changeKey);
if (destChanges.size() > 1) {
throw new InvalidChangeOperationException("Several changes with key " + changeKey + " reside on the same branch. " + "Cannot create a new patch set.");
}
try (BatchUpdate bu = batchUpdateFactory.create(db.get(), project, identifiedUser, now)) {
bu.setRepository(git, revWalk, oi);
Change.Id result;
if (destChanges.size() == 1) {
// The change key exists on the destination branch. The cherry pick
// will be added as a new patch set.
ChangeControl destCtl = targetRefControl.getProjectControl().controlFor(destChanges.get(0).notes());
result = insertPatchSet(bu, git, destCtl, cherryPickCommit, input);
} else {
// Change key not found on destination branch. We can create a new
// change.
String newTopic = null;
if (!Strings.isNullOrEmpty(sourceChangeTopic)) {
newTopic = sourceChangeTopic + "-" + newDest.getShortName();
}
result = createNewChange(bu, cherryPickCommit, targetRefControl.getRefName(), newTopic, sourceBranch, sourceCommit, input);
if (sourceChangeId != null && sourcePatchId != null) {
bu.addOp(sourceChangeId, new AddMessageToSourceChangeOp(changeMessagesUtil, sourcePatchId, destinationBranch, cherryPickCommit));
}
}
bu.execute();
return result;
}
} catch (MergeIdenticalTreeException | MergeConflictException e) {
throw new IntegrationException("Cherry pick failed: " + e.getMessage());
}
}
}
use of com.google.gerrit.extensions.restapi.MergeConflictException in project gerrit by GerritCodeReview.
the class RebaseChangeOp method rebaseCommit.
/**
* Rebase a commit.
*
* @param ctx repo context.
* @param original the commit to rebase.
* @param base base to rebase against.
* @return the rebased commit.
* @throws MergeConflictException the rebase failed due to a merge conflict.
* @throws IOException the merge failed for another reason.
*/
private RevCommit rebaseCommit(RepoContext ctx, RevCommit original, ObjectId base, String commitMessage) throws ResourceConflictException, IOException {
RevCommit parentCommit = original.getParent(0);
if (base.equals(parentCommit)) {
throw new ResourceConflictException("Change is already up to date.");
}
ThreeWayMerger merger = newMergeUtil().newThreeWayMerger(ctx.getInserter(), ctx.getRepoView().getConfig());
merger.setBase(parentCommit);
merger.merge(original, base);
if (merger.getResultTreeId() == null) {
throw new MergeConflictException("The change could not be rebased due to a conflict during merge.");
}
CommitBuilder cb = new CommitBuilder();
cb.setTreeId(merger.getResultTreeId());
cb.setParentId(base);
cb.setAuthor(original.getAuthorIdent());
cb.setMessage(commitMessage);
if (committerIdent != null) {
cb.setCommitter(committerIdent);
} else {
cb.setCommitter(ctx.getIdentifiedUser().newCommitterIdent(ctx.getWhen(), ctx.getTimeZone()));
}
ObjectId objectId = ctx.getInserter().insert(cb);
ctx.getInserter().flush();
return ctx.getRevWalk().parseCommit(objectId);
}
Aggregations