use of com.google.gerrit.server.git.CodeReviewCommit in project gerrit by GerritCodeReview.
the class MergeOp method getAlreadyAccepted.
private Set<RevCommit> getAlreadyAccepted(OpenRepo or, CodeReviewCommit branchTip) {
Set<RevCommit> alreadyAccepted = new HashSet<>();
if (branchTip != null) {
alreadyAccepted.add(branchTip);
}
try {
for (Ref r : or.repo.getRefDatabase().getRefsByPrefix(Constants.R_HEADS)) {
try {
CodeReviewCommit aac = or.rw.parseCommit(r.getObjectId());
if (!commitStatus.commits.values().contains(aac)) {
alreadyAccepted.add(aac);
}
} catch (IncorrectObjectTypeException iote) {
// Not a commit? Skip over it.
}
}
} catch (IOException e) {
throw new StorageException("Failed to determine already accepted commits.", e);
}
logger.atFine().log("Found %d existing heads: %s", alreadyAccepted.size(), alreadyAccepted);
return alreadyAccepted;
}
use of com.google.gerrit.server.git.CodeReviewCommit in project gerrit by GerritCodeReview.
the class SubmitStrategy method addOps.
/**
* Add operations to a batch update that execute this submit strategy.
*
* <p>Guarantees exactly one op is added to the update for each change in the input set.
*
* @param bu batch update to add operations to.
* @param toMerge the set of submitted commits that should be merged using this submit strategy.
* Implementations are responsible for ordering of commits, and will not modify the input in
* place.
*/
public final void addOps(BatchUpdate bu, Set<CodeReviewCommit> toMerge) {
List<SubmitStrategyOp> ops = buildOps(toMerge);
Set<CodeReviewCommit> added = Sets.newHashSetWithExpectedSize(ops.size());
for (SubmitStrategyOp op : ops) {
added.add(op.getCommit());
}
// First add ops for any implicitly merged changes.
List<CodeReviewCommit> difference = new ArrayList<>(Sets.difference(toMerge, added));
Collections.reverse(difference);
for (CodeReviewCommit c : difference) {
Change.Id id = c.change().getId();
bu.addOp(id, args.setPrivateOpFactory.create(false, null));
ImplicitIntegrateOp implicitIntegrateOp = new ImplicitIntegrateOp(args, c);
bu.addOp(id, implicitIntegrateOp);
maybeAddTestHelperOp(bu, id);
this.submitStrategyOps.add(implicitIntegrateOp);
}
// Then ops for explicitly merged changes
for (SubmitStrategyOp op : ops) {
bu.addOp(op.getId(), args.setPrivateOpFactory.create(false, null));
bu.addOp(op.getId(), op);
maybeAddTestHelperOp(bu, op.getId());
this.submitStrategyOps.add(op);
}
}
use of com.google.gerrit.server.git.CodeReviewCommit in project gerrit by GerritCodeReview.
the class SubmitStrategyListener method checkCommitStatus.
private List<Change.Id> checkCommitStatus() throws ResourceConflictException {
List<Change.Id> alreadyMerged = new ArrayList<>(commitStatus.getChangeIds().size());
for (Change.Id id : commitStatus.getChangeIds()) {
CodeReviewCommit commit = commitStatus.get(id);
CommitMergeStatus s = commit != null ? commit.getStatusCode() : null;
requireNonNull(s, String.format("change %d: change not processed by merge strategy", id.get()));
if (commit.getStatusMessage().isPresent()) {
logger.atFine().log("change %d: Status for commit %s is %s. %s", id.get(), commit.name(), s, commit.getStatusMessage().get());
} else {
logger.atFine().log("change %d: Status for commit %s is %s.", id.get(), commit.name(), s);
}
switch(s) {
case CLEAN_MERGE:
case CLEAN_REBASE:
case CLEAN_PICK:
case SKIPPED_IDENTICAL_TREE:
// Merge strategy accepted this change.
break;
case ALREADY_MERGED:
// Already an ancestor of tip.
alreadyMerged.add(commit.getPatchsetId().changeId());
break;
case PATH_CONFLICT:
case REBASE_MERGE_CONFLICT:
case MANUAL_RECURSIVE_MERGE:
case CANNOT_CHERRY_PICK_ROOT:
case CANNOT_REBASE_ROOT:
case NOT_FAST_FORWARD:
case EMPTY_COMMIT:
case MISSING_DEPENDENCY:
case FAST_FORWARD_INDEPENDENT_CHANGES:
// TODO(dborowitz): Reformat these messages to be more appropriate for
// short problem descriptions.
String message = s.getDescription();
if (commit.getStatusMessage().isPresent()) {
message += " " + commit.getStatusMessage().get();
}
commitStatus.problem(id, CharMatcher.is('\n').collapseFrom(message, ' '));
break;
default:
commitStatus.problem(id, "unspecified merge failure: " + s);
break;
}
}
commitStatus.maybeFailVerbose();
return alreadyMerged;
}
use of com.google.gerrit.server.git.CodeReviewCommit in project gerrit by GerritCodeReview.
the class SubmoduleCommits method updateSubmodule.
private RevCommit updateSubmodule(DirCache dc, DirCacheEditor ed, StringBuilder msgbuf, SubmoduleSubscription s) throws SubmoduleConflictException, IOException {
logger.atFine().log("Updating gitlink for %s", s);
OpenRepo subOr;
try {
subOr = orm.getRepo(s.getSubmodule().project());
} catch (NoSuchProjectException | IOException e) {
throw new StorageException("Cannot access submodule", e);
}
DirCacheEntry dce = dc.getEntry(s.getPath());
RevCommit oldCommit = null;
if (dce != null) {
if (!dce.getFileMode().equals(FileMode.GITLINK)) {
String errMsg = "Requested to update gitlink " + s.getPath() + " in " + s.getSubmodule().project().get() + " but entry " + "doesn't have gitlink file mode.";
throw new SubmoduleConflictException(errMsg);
}
// making things worse by updating the gitlink to something else.
try {
oldCommit = subOr.getCodeReviewRevWalk().parseCommit(dce.getObjectId());
} catch (IOException e) {
// Broken gitlink; sanity check failed. Warn and continue so the submit operation can
// proceed, it will just skip this gitlink update.
logger.atSevere().withCause(e).log("Failed to read commit %s", dce.getObjectId().name());
return null;
}
}
Optional<CodeReviewCommit> maybeNewCommit = branchTips.getTip(s.getSubmodule(), subOr);
if (!maybeNewCommit.isPresent()) {
// For whatever reason, this submodule was not updated as part of this submit batch, but the
// superproject is still subscribed to this branch. Re-read the ref to see if anything has
// changed since the last time the gitlink was updated, and roll that update into the same
// commit as all other submodule updates.
ed.add(new DeletePath(s.getPath()));
return null;
}
CodeReviewCommit newCommit = maybeNewCommit.get();
if (Objects.equals(newCommit, oldCommit)) {
// gitlink have already been updated for this submodule
return null;
}
ed.add(new PathEdit(s.getPath()) {
@Override
public void apply(DirCacheEntry ent) {
ent.setFileMode(FileMode.GITLINK);
ent.setObjectId(newCommit.getId());
}
});
if (verboseSuperProject != VerboseSuperprojectUpdate.FALSE) {
createSubmoduleCommitMsg(msgbuf, s, subOr, newCommit, oldCommit);
}
subOr.getCodeReviewRevWalk().parseBody(newCommit);
return newCommit;
}
use of com.google.gerrit.server.git.CodeReviewCommit in project gerrit by GerritCodeReview.
the class SubmoduleCommits method composeGitlinksCommit.
/**
* Create a separate gitlink commit
*
* @param subscriber superproject (and branch)
* @param subscriptions subprojects the superproject is subscribed to
* @return a new commit on top of subscriber with gitlinks update to the tips of the subprojects;
* empty if nothing has changed. Subproject tips are read from the cached branched tips
* (defaulting to the mergeOpRepoManager).
*/
Optional<CodeReviewCommit> composeGitlinksCommit(BranchNameKey subscriber, Collection<SubmoduleSubscription> subscriptions) throws IOException, SubmoduleConflictException {
OpenRepo or;
try {
or = orm.getRepo(subscriber.project());
} catch (NoSuchProjectException | IOException e) {
throw new StorageException("Cannot access superproject", e);
}
CodeReviewCommit currentCommit = branchTips.getTip(subscriber, or).orElseThrow(() -> new SubmoduleConflictException("The branch was probably deleted from the subscriber repository"));
StringBuilder msgbuf = new StringBuilder();
PersonIdent author = null;
DirCache dc = readTree(or.getCodeReviewRevWalk(), currentCommit);
DirCacheEditor ed = dc.editor();
int count = 0;
for (SubmoduleSubscription s : sortByPath(subscriptions)) {
if (count > 0) {
msgbuf.append("\n\n");
}
RevCommit newCommit = updateSubmodule(dc, ed, msgbuf, s);
count++;
if (newCommit != null) {
PersonIdent newCommitAuthor = newCommit.getAuthorIdent();
if (author == null) {
author = new PersonIdent(newCommitAuthor, myIdent.getWhen());
} else if (!author.getName().equals(newCommitAuthor.getName()) || !author.getEmailAddress().equals(newCommitAuthor.getEmailAddress())) {
author = myIdent;
}
}
}
ed.finish();
ObjectId newTreeId = dc.writeTree(or.ins);
// Gitlinks are already in the branch, return null
if (newTreeId.equals(currentCommit.getTree())) {
return Optional.empty();
}
CommitBuilder commit = new CommitBuilder();
commit.setTreeId(newTreeId);
commit.setParentId(currentCommit);
StringBuilder commitMsg = new StringBuilder("Update git submodules\n\n");
if (verboseSuperProject != VerboseSuperprojectUpdate.FALSE) {
commitMsg.append(msgbuf);
}
commit.setMessage(commitMsg.toString());
commit.setAuthor(author);
commit.setCommitter(myIdent);
ObjectId id = or.ins.insert(commit);
return Optional.of(or.getCodeReviewRevWalk().parseCommit(id));
}
Aggregations