private void setMerged(Change c, ChangeMessage msg, ObjectId mergeResultRev) throws OrmException, IOException { logDebug("Setting change {} merged", c.getId()); ChangeUpdate update = null; final PatchSetApproval submitter; PatchSet merged; try { db.changes().beginTransaction(c.getId()); // We must pull the patchset out of commits, because the patchset ID is // modified when using the cherry-pick merge strategy. CodeReviewCommit commit = commits.get(c.getId()); PatchSet.Id mergedId = commit.change().currentPatchSetId(); merged = db.patchSets().get(mergedId); c = setMergedPatchSet(c.getId(), mergedId); submitter = approvalsUtil.getSubmitter(db, commit.notes(), mergedId); ChangeControl control = commit.getControl(); update = updateFactory.create(control, c.getLastUpdatedOn()); // TODO(yyonas): we need to be able to change the author of the message // is not the person for whom the change was made. addMergedMessage // did this in the past. if (msg != null) { cmUtil.addChangeMessage(db, update, msg); } db.commit(); } finally { db.rollback(); } update.commit(); indexer.index(db, c); try { mergedSenderFactory .create(c.getId(), submitter != null ? submitter.getAccountId() : null) .sendAsync(); } catch (Exception e) { log.error("Cannot email merged notification for " + c.getId(), e); } if (submitter != null && mergeResultRev != null) { try { hooks.doChangeMergedHook( c, accountCache.get(submitter.getAccountId()).getAccount(), merged, db, mergeResultRev.name()); } catch (OrmException ex) { logError("Cannot run hook for submitted patch set " + c.getId(), ex); } } }
private void setNew(ChangeNotes notes, final ChangeMessage msg) throws NoSuchChangeException, IOException { Change c = notes.getChange(); Change change = null; ChangeUpdate update = null; try { db.changes().beginTransaction(c.getId()); try { change = db.changes() .atomicUpdate( c.getId(), new AtomicUpdate<Change>() { @Override public Change update(Change c) { if (c.getStatus().isOpen()) { c.setStatus(Change.Status.NEW); ChangeUtil.updated(c); } return c; } }); ChangeControl control = changeControl(change); // TODO(yyonas): atomic change is not propagated. update = updateFactory.create(control, c.getLastUpdatedOn()); if (msg != null) { cmUtil.addChangeMessage(db, update, msg); } db.commit(); } finally { db.rollback(); } } catch (OrmException err) { logWarn("Cannot record merge failure message", err); } if (update != null) { update.commit(); } indexer.index(db, change); PatchSetApproval submitter = null; try { submitter = approvalsUtil.getSubmitter(db, notes, notes.getChange().currentPatchSetId()); } catch (Exception e) { logError("Cannot get submitter for change " + notes.getChangeId(), e); } if (submitter != null) { try { hooks.doMergeFailedHook( c, accountCache.get(submitter.getAccountId()).getAccount(), db.patchSets().get(c.currentPatchSetId()), msg.getMessage(), db); } catch (OrmException ex) { logError("Cannot run hook for merge failed " + c.getId(), ex); } } }
private Set<Change.Id> parseChangeId(String idstr) throws UnloggedFailure, OrmException { Set<Change.Id> matched = new HashSet<>(4); boolean isCommit = idstr.matches("^([0-9a-fA-F]{4," + RevId.LEN + "})$"); // By newer style changeKey? // boolean changeKeyParses = idstr.matches("^I[0-9a-f]*$"); if (changeKeyParses) { for (ChangeData cd : queryProvider.get().byKeyPrefix(idstr)) { matchChange(matched, cd.change()); } } // By commit? // if (isCommit) { RevId id = new RevId(idstr); ResultSet<PatchSet> patches; if (id.isComplete()) { patches = db.patchSets().byRevision(id); } else { patches = db.patchSets().byRevisionRange(id, id.max()); } for (PatchSet ps : patches) { matchChange(matched, ps.getId().getParentKey()); } } // By older style changeId? // boolean changeIdParses = false; if (idstr.matches("^[1-9][0-9]*$")) { Change.Id id; try { id = Change.Id.parse(idstr); changeIdParses = true; } catch (IllegalArgumentException e) { id = null; changeIdParses = false; } if (changeIdParses) { matchChange(matched, id); } } if (!changeKeyParses && !isCommit && !changeIdParses) { throw error("\"" + idstr + "\" is not a valid change"); } switch (matched.size()) { case 0: throw error("\"" + idstr + "\" no such change"); case 1: return matched; default: throw error("\"" + idstr + "\" matches multiple changes"); } }