use of com.google.gerrit.server.git.CodeReviewCommit in project gerrit by GerritCodeReview.
the class MergeAlways method buildOps.
@Override
public List<SubmitStrategyOp> buildOps(Collection<CodeReviewCommit> toMerge) throws IntegrationException {
List<CodeReviewCommit> sorted = args.mergeUtil.reduceToMinimalMerge(args.mergeSorter, toMerge);
List<SubmitStrategyOp> ops = new ArrayList<>(sorted.size());
if (args.mergeTip.getInitialTip() == null && !sorted.isEmpty()) {
// The branch is unborn. Take a fast-forward resolution to
// create the branch.
CodeReviewCommit first = sorted.remove(0);
ops.add(new FastForwardOp(args, first));
}
while (!sorted.isEmpty()) {
CodeReviewCommit n = sorted.remove(0);
ops.add(new MergeOneOp(args, n));
}
return ops;
}
use of com.google.gerrit.server.git.CodeReviewCommit in project gerrit by GerritCodeReview.
the class MergeIfNecessary method buildOps.
@Override
public List<SubmitStrategyOp> buildOps(Collection<CodeReviewCommit> toMerge) throws IntegrationException {
List<CodeReviewCommit> sorted = args.mergeUtil.reduceToMinimalMerge(args.mergeSorter, toMerge);
List<SubmitStrategyOp> ops = new ArrayList<>(sorted.size());
if (args.mergeTip.getInitialTip() == null || !args.submoduleOp.hasSubscription(args.destBranch)) {
CodeReviewCommit firstFastForward = args.mergeUtil.getFirstFastForward(args.mergeTip.getInitialTip(), args.rw, sorted);
if (firstFastForward != null && !firstFastForward.equals(args.mergeTip.getInitialTip())) {
ops.add(new FastForwardOp(args, firstFastForward));
}
}
// For every other commit do a pair-wise merge.
while (!sorted.isEmpty()) {
CodeReviewCommit n = sorted.remove(0);
ops.add(new MergeOneOp(args, n));
}
return ops;
}
use of com.google.gerrit.server.git.CodeReviewCommit 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.server.git.CodeReviewCommit in project gerrit by GerritCodeReview.
the class SubmitStrategyOp method updateRepo.
@Override
public final void updateRepo(RepoContext ctx) throws Exception {
logDebug("{}#updateRepo for change {}", getClass().getSimpleName(), toMerge.change().getId());
checkState(ctx.getRevWalk() == args.rw, "SubmitStrategyOp requires callers to call BatchUpdate#setRepository with exactly the same" + " CodeReviewRevWalk instance from the SubmitStrategy.Arguments: %s != %s", ctx.getRevWalk(), args.rw);
// Run the submit strategy implementation and record the merge tip state so
// we can create the ref update.
CodeReviewCommit tipBefore = args.mergeTip.getCurrentTip();
alreadyMerged = getAlreadyMergedCommit(ctx);
if (alreadyMerged == null) {
updateRepoImpl(ctx);
} else {
logDebug("Already merged as {}", alreadyMerged.name());
}
CodeReviewCommit tipAfter = args.mergeTip.getCurrentTip();
if (Objects.equals(tipBefore, tipAfter)) {
logDebug("Did not move tip", getClass().getSimpleName());
return;
} else if (tipAfter == null) {
logDebug("No merge tip, no update to perform");
return;
}
logDebug("Moved tip from {} to {}", tipBefore, tipAfter);
checkProjectConfig(ctx, tipAfter);
// Needed by postUpdate, at which point mergeTip will have advanced further,
// so it's easier to just snapshot the command.
command = new ReceiveCommand(firstNonNull(tipBefore, ObjectId.zeroId()), tipAfter, getDest().get());
ctx.addRefUpdate(command);
args.submoduleOp.addBranchTip(getDest(), tipAfter);
}
use of com.google.gerrit.server.git.CodeReviewCommit in project gerrit by GerritCodeReview.
the class RebaseSubmitStrategy method buildOps.
@Override
public List<SubmitStrategyOp> buildOps(Collection<CodeReviewCommit> toMerge) throws IntegrationException {
List<CodeReviewCommit> sorted;
try {
sorted = args.rebaseSorter.sort(toMerge);
} catch (IOException e) {
throw new IntegrationException("Commit sorting failed", e);
}
List<SubmitStrategyOp> ops = new ArrayList<>(sorted.size());
boolean first = true;
for (CodeReviewCommit c : sorted) {
if (c.getParentCount() > 1) {
// Since there is a merge commit, sort and prune again using
// MERGE_IF_NECESSARY semantics to avoid creating duplicate
// commits.
//
sorted = args.mergeUtil.reduceToMinimalMerge(args.mergeSorter, sorted);
break;
}
}
while (!sorted.isEmpty()) {
CodeReviewCommit n = sorted.remove(0);
if (first && args.mergeTip.getInitialTip() == null) {
// TODO(tandrii): Cherry-Pick strategy does this too, but it's wrong
// and can be fixed.
ops.add(new FastForwardOp(args, n));
} else if (n.getParentCount() == 0) {
ops.add(new RebaseRootOp(n));
} else if (n.getParentCount() == 1) {
ops.add(new RebaseOneOp(n));
} else {
ops.add(new RebaseMultipleParentsOp(n));
}
first = false;
}
return ops;
}
Aggregations