Store ChangeControl instead of ChangeNotes in CodeReviewCommit

We want to be able to use ApprovalCopier when generating the list of
approvals that goes in the cherry-pick commit message, which requires
the ChangeControl.

Exposed a couple of subtle bugs in merge code expecting one Change
object to be mutated when it was in fact another.

Change-Id: Iad025a0b7a54306bc3b636cc28f484ee0baf534b
This commit is contained in:
Dave Borowitz 2014-02-05 17:41:17 -08:00
parent 9aaec77200
commit c15bbc845f
10 changed files with 119 additions and 116 deletions

View File

@ -292,7 +292,7 @@ public class RebaseChange {
rebasedCommit = revWalk.parseCommit(newId); rebasedCommit = revWalk.parseCommit(newId);
final ChangeControl changeControl = final ChangeControl changeControl =
changeControlFactory.validateFor(change.getId(), uploader); changeControlFactory.validateFor(change, uploader);
PatchSetInserter patchSetInserter = patchSetInserterFactory PatchSetInserter patchSetInserter = patchSetInserterFactory
.create(git, revWalk, changeControl, rebasedCommit) .create(git, revWalk, changeControl, rebasedCommit)

View File

@ -22,8 +22,10 @@ import com.google.gerrit.reviewdb.client.PatchSetApproval;
import com.google.gerrit.reviewdb.client.RevId; import com.google.gerrit.reviewdb.client.RevId;
import com.google.gerrit.reviewdb.server.ReviewDb; import com.google.gerrit.reviewdb.server.ReviewDb;
import com.google.gerrit.server.ChangeUtil; import com.google.gerrit.server.ChangeUtil;
import com.google.gerrit.server.IdentifiedUser;
import com.google.gerrit.server.extensions.events.GitReferenceUpdated; import com.google.gerrit.server.extensions.events.GitReferenceUpdated;
import com.google.gerrit.server.patch.PatchSetInfoFactory; import com.google.gerrit.server.patch.PatchSetInfoFactory;
import com.google.gerrit.server.project.NoSuchChangeException;
import com.google.gerrit.server.util.TimeUtil; import com.google.gerrit.server.util.TimeUtil;
import com.google.gwtorm.server.OrmException; import com.google.gwtorm.server.OrmException;
@ -118,29 +120,30 @@ public class CherryPick extends SubmitStrategy {
} }
} }
} catch (IOException e) { } catch (NoSuchChangeException | IOException | OrmException e) {
throw new MergeException("Cannot merge " + n.name(), e);
} catch (OrmException e) {
throw new MergeException("Cannot merge " + n.name(), e); throw new MergeException("Cannot merge " + n.name(), e);
} }
} }
return newMergeTip; return newMergeTip;
} }
private CodeReviewCommit writeCherryPickCommit(final CodeReviewCommit mergeTip, final CodeReviewCommit n) private CodeReviewCommit writeCherryPickCommit(CodeReviewCommit mergeTip,
throws IOException, OrmException { CodeReviewCommit n) throws IOException, OrmException,
NoSuchChangeException {
args.rw.parseBody(n); args.rw.parseBody(n);
final PatchSetApproval submitAudit = args.mergeUtil.getSubmitter(n); final PatchSetApproval submitAudit = args.mergeUtil.getSubmitter(n);
IdentifiedUser cherryPickUser;
PersonIdent cherryPickCommitterIdent; PersonIdent cherryPickCommitterIdent;
if (submitAudit != null) { if (submitAudit != null) {
cherryPickCommitterIdent = cherryPickUser =
args.identifiedUserFactory.create(submitAudit.getAccountId()) args.identifiedUserFactory.create(submitAudit.getAccountId());
.newCommitterIdent(submitAudit.getGranted(), cherryPickCommitterIdent = cherryPickUser.newCommitterIdent(
args.myIdent.getTimeZone()); submitAudit.getGranted(), args.myIdent.getTimeZone());
} else { } else {
cherryPickUser = args.identifiedUserFactory.create(n.change().getOwner());
cherryPickCommitterIdent = args.myIdent; cherryPickCommitterIdent = args.myIdent;
} }
@ -156,7 +159,7 @@ public class CherryPick extends SubmitStrategy {
} }
PatchSet.Id id = PatchSet.Id id =
ChangeUtil.nextPatchSetId(args.repo, n.getChange().currentPatchSetId()); ChangeUtil.nextPatchSetId(args.repo, n.change().currentPatchSetId());
final PatchSet ps = new PatchSet(id); final PatchSet ps = new PatchSet(id);
ps.setCreatedOn(TimeUtil.nowTs()); ps.setCreatedOn(TimeUtil.nowTs());
ps.setUploader(submitAudit.getAccountId()); ps.setUploader(submitAudit.getAccountId());
@ -164,17 +167,17 @@ public class CherryPick extends SubmitStrategy {
final RefUpdate ru; final RefUpdate ru;
args.db.changes().beginTransaction(n.getChange().getId()); args.db.changes().beginTransaction(n.change().getId());
try { try {
insertAncestors(args.db, ps.getId(), newCommit); insertAncestors(args.db, ps.getId(), newCommit);
args.db.patchSets().insert(Collections.singleton(ps)); args.db.patchSets().insert(Collections.singleton(ps));
n.getChange() n.change()
.setCurrentPatchSet(patchSetInfoFactory.get(newCommit, ps.getId())); .setCurrentPatchSet(patchSetInfoFactory.get(newCommit, ps.getId()));
args.db.changes().update(Collections.singletonList(n.getChange())); args.db.changes().update(Collections.singletonList(n.change()));
final List<PatchSetApproval> approvals = Lists.newArrayList(); final List<PatchSetApproval> approvals = Lists.newArrayList();
for (PatchSetApproval a for (PatchSetApproval a
: args.approvalsUtil.byPatchSet(args.db, n.notes, n.patchsetId)) { : args.approvalsUtil.byPatchSet(args.db, n.notes(), n.patchsetId)) {
approvals.add(new PatchSetApproval(ps.getId(), a)); approvals.add(new PatchSetApproval(ps.getId(), a));
} }
// TODO(dborowitz): This doesn't copy labels in the notedb. We should // TODO(dborowitz): This doesn't copy labels in the notedb. We should
@ -188,7 +191,7 @@ public class CherryPick extends SubmitStrategy {
ru.disableRefLog(); ru.disableRefLog();
if (ru.update(args.rw) != RefUpdate.Result.NEW) { if (ru.update(args.rw) != RefUpdate.Result.NEW) {
throw new IOException(String.format( throw new IOException(String.format(
"Failed to create ref %s in %s: %s", ps.getRefName(), n.getChange() "Failed to create ref %s in %s: %s", ps.getRefName(), n.change()
.getDest().getParentKey().get(), ru.getResult())); .getDest().getParentKey().get(), ru.getResult()));
} }
@ -197,10 +200,12 @@ public class CherryPick extends SubmitStrategy {
args.db.rollback(); args.db.rollback();
} }
gitRefUpdated.fire(n.getChange().getProject(), ru); gitRefUpdated.fire(n.change().getProject(), ru);
newCommit.copyFrom(n); newCommit.copyFrom(n);
newCommit.statusCode = CommitMergeStatus.CLEAN_PICK; newCommit.statusCode = CommitMergeStatus.CLEAN_PICK;
newCommit.control =
args.changeControlFactory.controlFor(n.change(), cherryPickUser);
newCommits.put(newCommit.patchsetId.getParentKey(), newCommit); newCommits.put(newCommit.patchsetId.getParentKey(), newCommit);
setRefLogIdent(submitAudit); setRefLogIdent(submitAudit);
return newCommit; return newCommit;

View File

@ -17,6 +17,7 @@ package com.google.gerrit.server.git;
import com.google.gerrit.reviewdb.client.Change; import com.google.gerrit.reviewdb.client.Change;
import com.google.gerrit.reviewdb.client.PatchSet; import com.google.gerrit.reviewdb.client.PatchSet;
import com.google.gerrit.server.notedb.ChangeNotes; import com.google.gerrit.server.notedb.ChangeNotes;
import com.google.gerrit.server.project.ChangeControl;
import org.eclipse.jgit.lib.AnyObjectId; import org.eclipse.jgit.lib.AnyObjectId;
import org.eclipse.jgit.lib.ObjectId; import org.eclipse.jgit.lib.ObjectId;
@ -40,8 +41,8 @@ public class CodeReviewCommit extends RevCommit {
*/ */
PatchSet.Id patchsetId; PatchSet.Id patchsetId;
/** Change info loaded from notes. */ /** Change control for the change owner. */
public ChangeNotes notes; ChangeControl control;
/** /**
* Ordinal position of this commit within the submit queue. * Ordinal position of this commit within the submit queue.
@ -64,15 +65,19 @@ public class CodeReviewCommit extends RevCommit {
super(id); super(id);
} }
public ChangeNotes notes() {
return control.getNotes();
}
void copyFrom(final CodeReviewCommit src) { void copyFrom(final CodeReviewCommit src) {
control = src.control;
patchsetId = src.patchsetId; patchsetId = src.patchsetId;
notes = src.notes;
originalOrder = src.originalOrder; originalOrder = src.originalOrder;
statusCode = src.statusCode; statusCode = src.statusCode;
missing = src.missing; missing = src.missing;
} }
Change getChange() { Change change() {
return notes.getChange(); return control.getChange();
} }
} }

View File

@ -279,8 +279,8 @@ public class MergeOp {
for (final CodeReviewCommit commit : potentiallyStillSubmittableOnNextRun) { for (final CodeReviewCommit commit : potentiallyStillSubmittableOnNextRun) {
final Capable capable = isSubmitStillPossible(commit); final Capable capable = isSubmitStillPossible(commit);
if (capable != Capable.OK) { if (capable != Capable.OK) {
sendMergeFail(commit.notes, sendMergeFail(commit.notes(),
message(commit.getChange(), capable.getMessage()), false); message(commit.change(), capable.getMessage()), false);
} }
} }
} catch (NoSuchProjectException noProject) { } catch (NoSuchProjectException noProject) {
@ -327,7 +327,12 @@ public class MergeOp {
} }
for (CodeReviewCommit missingCommit : commit.missing) { for (CodeReviewCommit missingCommit : commit.missing) {
try {
loadChangeInfo(missingCommit); loadChangeInfo(missingCommit);
} catch (NoSuchChangeException | OrmException e) {
log.error("Cannot check if missing commits can be submitted", e);
return false;
}
if (missingCommit.patchsetId == null) { if (missingCommit.patchsetId == null) {
// The commit doesn't have a patch set, so it cannot be // The commit doesn't have a patch set, so it cannot be
@ -336,7 +341,7 @@ public class MergeOp {
return false; return false;
} }
if (!missingCommit.getChange().currentPatchSetId().equals( if (!missingCommit.change().currentPatchSetId().equals(
missingCommit.patchsetId)) { missingCommit.patchsetId)) {
// If the missing commit is not the current patch set, // If the missing commit is not the current patch set,
// the change must be rebased to use the proper parent. // the change must be rebased to use the proper parent.
@ -519,7 +524,12 @@ public class MergeOp {
continue; continue;
} }
commit.notes = notesFactory.create(chg); try {
commit.control = changeControlFactory.controlFor(chg,
identifiedUserFactory.create(chg.getOwner()));
} catch (NoSuchChangeException e) {
throw new MergeException("Failed to validate changes", e);
}
commit.patchsetId = ps.getId(); commit.patchsetId = ps.getId();
commit.originalOrder = commitOrder++; commit.originalOrder = commitOrder++;
commits.put(changeId, commit); commits.put(changeId, commit);
@ -544,7 +554,7 @@ public class MergeOp {
} }
} }
final SubmitType submitType = getSubmitType(chg, ps); final SubmitType submitType = getSubmitType(commit.control, ps);
if (submitType == null) { if (submitType == null) {
commits.put(changeId, commits.put(changeId,
CodeReviewCommit.error(CommitMergeStatus.NO_SUBMIT_TYPE)); CodeReviewCommit.error(CommitMergeStatus.NO_SUBMIT_TYPE));
@ -559,21 +569,13 @@ public class MergeOp {
return toSubmit; return toSubmit;
} }
private SubmitType getSubmitType(final Change change, final PatchSet ps) { private SubmitType getSubmitType(ChangeControl ctl, PatchSet ps) {
try { SubmitTypeRecord r = ctl.getSubmitTypeRecord(db, ps);
final SubmitTypeRecord r =
changeControlFactory.controlFor(change,
identifiedUserFactory.create(change.getOwner()))
.getSubmitTypeRecord(db, ps);
if (r.status != SubmitTypeRecord.Status.OK) { if (r.status != SubmitTypeRecord.Status.OK) {
log.error("Failed to get submit type for " + change.getKey()); log.error("Failed to get submit type for " + ctl.getChange().getKey());
return null; return null;
} }
return r.type; return r.type;
} catch (NoSuchChangeException e) {
log.error("Failed to get submit type for " + change.getKey(), e);
return null;
}
} }
private void updateBranch(final SubmitStrategy strategy, private void updateBranch(final SubmitStrategy strategy,
@ -623,7 +625,7 @@ public class MergeOp {
Account account = null; Account account = null;
PatchSetApproval submitter = approvalsUtil.getSubmitter( PatchSetApproval submitter = approvalsUtil.getSubmitter(
db, mergeTip.notes, mergeTip.patchsetId); db, mergeTip.notes(), mergeTip.patchsetId);
if (submitter != null) { if (submitter != null) {
account = accountCache.get(submitter.getAccountId()).getAccount(); account = accountCache.get(submitter.getAccountId()).getAccount();
} }
@ -723,7 +725,7 @@ public class MergeOp {
private Capable isSubmitStillPossible(final CodeReviewCommit commit) { private Capable isSubmitStillPossible(final CodeReviewCommit commit) {
final Capable capable; final Capable capable;
final Change c = commit.getChange(); final Change c = commit.change();
final boolean submitStillPossible = isSubmitForMissingCommitsStillPossible(commit); final boolean submitStillPossible = isSubmitForMissingCommitsStillPossible(commit);
final long now = TimeUtil.nowMs(); final long now = TimeUtil.nowMs();
final long waitUntil = c.getLastUpdatedOn().getTime() + DEPENDENCY_DELAY; final long waitUntil = c.getLastUpdatedOn().getTime() + DEPENDENCY_DELAY;
@ -748,7 +750,7 @@ public class MergeOp {
m.append("\n"); m.append("\n");
for (CodeReviewCommit missingCommit : commit.missing) { for (CodeReviewCommit missingCommit : commit.missing) {
m.append("* "); m.append("* ");
m.append(missingCommit.getChange().getKey().get()); m.append(missingCommit.change().getKey().get());
m.append("\n"); m.append("\n");
} }
capable = new Capable(m.toString()); capable = new Capable(m.toString());
@ -767,10 +769,10 @@ public class MergeOp {
m.append("* Depends on patch set "); m.append("* Depends on patch set ");
m.append(missingCommit.patchsetId.get()); m.append(missingCommit.patchsetId.get());
m.append(" of "); m.append(" of ");
m.append(missingCommit.getChange().getKey().abbreviate()); m.append(missingCommit.change().getKey().abbreviate());
if (missingCommit.patchsetId.get() != missingCommit.getChange().currentPatchSetId().get()) { if (missingCommit.patchsetId.get() != missingCommit.change().currentPatchSetId().get()) {
m.append(", however the current patch set is "); m.append(", however the current patch set is ");
m.append(missingCommit.getChange().currentPatchSetId().get()); m.append(missingCommit.change().currentPatchSetId().get());
} }
m.append(".\n"); m.append(".\n");
@ -788,18 +790,16 @@ public class MergeOp {
return capable; return capable;
} }
private void loadChangeInfo(final CodeReviewCommit commit) { private void loadChangeInfo(final CodeReviewCommit commit)
if (commit.notes == null) { throws NoSuchChangeException, OrmException {
try { if (commit.control == null) {
List<PatchSet> matches = List<PatchSet> matches =
db.patchSets().byRevision(new RevId(commit.name())).toList(); db.patchSets().byRevision(new RevId(commit.name())).toList();
if (matches.size() == 1) { if (matches.size() == 1) {
final PatchSet ps = matches.get(0); PatchSet ps = matches.get(0);
commit.patchsetId = ps.getId(); commit.patchsetId = ps.getId();
commit.notes = commit.control =
notesFactory.create(db.changes().get(ps.getId().getParentKey())); changeControl(db.changes().get(ps.getId().getParentKey()));
}
} catch (OrmException e) {
} }
} }
} }
@ -825,10 +825,10 @@ public class MergeOp {
// We must pull the patchset out of commits, because the patchset ID is // We must pull the patchset out of commits, because the patchset ID is
// modified when using the cherry-pick merge strategy. // modified when using the cherry-pick merge strategy.
CodeReviewCommit commit = commits.get(c.getId()); CodeReviewCommit commit = commits.get(c.getId());
PatchSet.Id merged = commit.getChange().currentPatchSetId(); PatchSet.Id merged = commit.change().currentPatchSetId();
c = setMergedPatchSet(c.getId(), merged); c = setMergedPatchSet(c.getId(), merged);
PatchSetApproval submitter = PatchSetApproval submitter =
approvalsUtil.getSubmitter(db, commit.notes, merged); approvalsUtil.getSubmitter(db, commit.notes(), merged);
addMergedMessage(submitter, msg); addMergedMessage(submitter, msg);
db.commit(); db.commit();
@ -904,9 +904,7 @@ public class MergeOp {
} }
try { try {
final ChangeControl control = changeControlFactory.controlFor(c, MergedSender cm = mergedSenderFactory.create(changeControl(c));
identifiedUserFactory.create(c.getOwner()));
final MergedSender cm = mergedSenderFactory.create(control);
if (from != null) { if (from != null) {
cm.setFrom(from.getAccountId()); cm.setFrom(from.getAccountId());
} }
@ -924,8 +922,13 @@ public class MergeOp {
})); }));
} }
private ChangeControl changeControl(Change c) throws NoSuchChangeException {
return changeControlFactory.controlFor(
c, identifiedUserFactory.create(c.getOwner()));
}
private void setNew(CodeReviewCommit c, ChangeMessage msg) { private void setNew(CodeReviewCommit c, ChangeMessage msg) {
sendMergeFail(c.notes, msg, true); sendMergeFail(c.notes(), msg, true);
} }
private void setNew(Change c, ChangeMessage msg) throws OrmException { private void setNew(Change c, ChangeMessage msg) throws OrmException {

View File

@ -168,7 +168,7 @@ public class MergeUtil {
} }
PatchSetApproval getSubmitter(CodeReviewCommit c) { PatchSetApproval getSubmitter(CodeReviewCommit c) {
return approvalsUtil.getSubmitter(db.get(), c.notes, c.patchsetId); return approvalsUtil.getSubmitter(db.get(), c.notes(), c.patchsetId);
} }
public RevCommit createCherryPickFromCommit(Repository repo, public RevCommit createCherryPickFromCommit(Repository repo,
@ -217,10 +217,10 @@ public class MergeUtil {
msgbuf.append('\n'); msgbuf.append('\n');
} }
if (!contains(footers, CHANGE_ID, n.getChange().getKey().get())) { if (!contains(footers, CHANGE_ID, n.change().getKey().get())) {
msgbuf.append(CHANGE_ID.getName()); msgbuf.append(CHANGE_ID.getName());
msgbuf.append(": "); msgbuf.append(": ");
msgbuf.append(n.getChange().getKey().get()); msgbuf.append(n.change().getKey().get());
msgbuf.append('\n'); msgbuf.append('\n');
} }
@ -313,7 +313,7 @@ public class MergeUtil {
private List<PatchSetApproval> safeGetApprovals(CodeReviewCommit n) { private List<PatchSetApproval> safeGetApprovals(CodeReviewCommit n) {
try { try {
return approvalsUtil.byPatchSet(db.get(), n.notes, n.patchsetId); return approvalsUtil.byPatchSet(db.get(), n.notes(), n.patchsetId);
} catch (OrmException e) { } catch (OrmException e) {
log.error("Can't read approval records for " + n.patchsetId, e); log.error("Can't read approval records for " + n.patchsetId, e);
return Collections.emptyList(); return Collections.emptyList();
@ -587,7 +587,10 @@ public class MergeUtil {
mergeCommit.setCommitter(myIdent); mergeCommit.setCommitter(myIdent);
mergeCommit.setMessage(msgbuf.toString()); mergeCommit.setMessage(msgbuf.toString());
return (CodeReviewCommit) rw.parseCommit(commit(inserter, mergeCommit)); CodeReviewCommit mergeResult =
(CodeReviewCommit) rw.parseCommit(commit(inserter, mergeCommit));
mergeResult.control = n.control;
return mergeResult;
} }
private String summarize(RevWalk rw, List<CodeReviewCommit> merged) private String summarize(RevWalk rw, List<CodeReviewCommit> merged)
@ -600,8 +603,8 @@ public class MergeUtil {
LinkedHashSet<String> topics = new LinkedHashSet<>(4); LinkedHashSet<String> topics = new LinkedHashSet<>(4);
for (CodeReviewCommit c : merged) { for (CodeReviewCommit c : merged) {
if (!Strings.isNullOrEmpty(c.getChange().getTopic())) { if (!Strings.isNullOrEmpty(c.change().getTopic())) {
topics.add(c.getChange().getTopic()); topics.add(c.change().getTopic());
} }
} }
@ -616,7 +619,7 @@ public class MergeUtil {
new Function<CodeReviewCommit, String>() { new Function<CodeReviewCommit, String>() {
@Override @Override
public String apply(CodeReviewCommit in) { public String apply(CodeReviewCommit in) {
return in.getChange().getKey().abbreviate(); return in.change().getKey().abbreviate();
} }
})), })),
merged.size() > 5 ? ", ..." : ""); merged.size() > 5 ? ", ..." : "");

View File

@ -22,6 +22,7 @@ import com.google.gerrit.server.IdentifiedUser;
import com.google.gerrit.server.change.PatchSetInserter.ValidatePolicy; import com.google.gerrit.server.change.PatchSetInserter.ValidatePolicy;
import com.google.gerrit.server.changedetail.PathConflictException; import com.google.gerrit.server.changedetail.PathConflictException;
import com.google.gerrit.server.changedetail.RebaseChange; import com.google.gerrit.server.changedetail.RebaseChange;
import com.google.gerrit.server.patch.PatchSetInfoFactory;
import com.google.gerrit.server.project.InvalidChangeOperationException; import com.google.gerrit.server.project.InvalidChangeOperationException;
import com.google.gerrit.server.project.NoSuchChangeException; import com.google.gerrit.server.project.NoSuchChangeException;
import com.google.gwtorm.server.OrmException; import com.google.gwtorm.server.OrmException;
@ -35,14 +36,17 @@ import java.util.List;
import java.util.Map; import java.util.Map;
public class RebaseIfNecessary extends SubmitStrategy { public class RebaseIfNecessary extends SubmitStrategy {
private final PatchSetInfoFactory patchSetInfoFactory;
private final RebaseChange rebaseChange; private final RebaseChange rebaseChange;
private final Map<Change.Id, CodeReviewCommit> newCommits; private final Map<Change.Id, CodeReviewCommit> newCommits;
private final PersonIdent committerIdent; private final PersonIdent committerIdent;
RebaseIfNecessary(final SubmitStrategy.Arguments args, RebaseIfNecessary(SubmitStrategy.Arguments args,
final RebaseChange rebaseChange, PersonIdent committerIdent) { PatchSetInfoFactory patchSetInfoFactory,
RebaseChange rebaseChange,
PersonIdent committerIdent) {
super(args); super(args);
this.patchSetInfoFactory = patchSetInfoFactory;
this.rebaseChange = rebaseChange; this.rebaseChange = rebaseChange;
this.newCommits = new HashMap<Change.Id, CodeReviewCommit>(); this.newCommits = new HashMap<Change.Id, CodeReviewCommit>();
this.committerIdent = committerIdent; this.committerIdent = committerIdent;
@ -82,7 +86,7 @@ public class RebaseIfNecessary extends SubmitStrategy {
args.mergeUtil.getSubmitter(n).getAccountId()); args.mergeUtil.getSubmitter(n).getAccountId());
final PatchSet newPatchSet = final PatchSet newPatchSet =
rebaseChange.rebase(args.repo, args.rw, args.inserter, rebaseChange.rebase(args.repo, args.rw, args.inserter,
n.patchsetId, n.getChange(), uploader, n.patchsetId, n.change(), uploader,
newMergeTip, args.mergeUtil, committerIdent, newMergeTip, args.mergeUtil, committerIdent,
false, false, ValidatePolicy.NONE); false, false, ValidatePolicy.NONE);
@ -91,7 +95,7 @@ public class RebaseIfNecessary extends SubmitStrategy {
// describes the change being submitted. // describes the change being submitted.
List<PatchSetApproval> approvals = Lists.newArrayList(); List<PatchSetApproval> approvals = Lists.newArrayList();
for (PatchSetApproval a : args.approvalsUtil.byPatchSet( for (PatchSetApproval a : args.approvalsUtil.byPatchSet(
args.db, n.notes, n.patchsetId)) { args.db, n.notes(), n.patchsetId)) {
approvals.add(new PatchSetApproval(newPatchSet.getId(), a)); approvals.add(new PatchSetApproval(newPatchSet.getId(), a));
} }
args.db.patchSetApprovals().insert(approvals); args.db.patchSetApprovals().insert(approvals);
@ -99,22 +103,19 @@ public class RebaseIfNecessary extends SubmitStrategy {
newMergeTip = newMergeTip =
(CodeReviewCommit) args.rw.parseCommit(ObjectId (CodeReviewCommit) args.rw.parseCommit(ObjectId
.fromString(newPatchSet.getRevision().get())); .fromString(newPatchSet.getRevision().get()));
n.change().setCurrentPatchSet(
patchSetInfoFactory.get(newMergeTip, newPatchSet.getId()));
newMergeTip.copyFrom(n); newMergeTip.copyFrom(n);
newMergeTip.control =
args.changeControlFactory.controlFor(n.change(), uploader);
newMergeTip.patchsetId = newPatchSet.getId(); newMergeTip.patchsetId = newPatchSet.getId();
newMergeTip.notes = args.notesFactory.create(
args.db.changes().get(newPatchSet.getId().getParentKey()));
newMergeTip.statusCode = CommitMergeStatus.CLEAN_REBASE; newMergeTip.statusCode = CommitMergeStatus.CLEAN_REBASE;
newCommits.put(newPatchSet.getId().getParentKey(), newMergeTip); newCommits.put(newPatchSet.getId().getParentKey(), newMergeTip);
setRefLogIdent(args.mergeUtil.getSubmitter(n)); setRefLogIdent(args.mergeUtil.getSubmitter(n));
} catch (PathConflictException e) { } catch (PathConflictException e) {
n.statusCode = CommitMergeStatus.PATH_CONFLICT; n.statusCode = CommitMergeStatus.PATH_CONFLICT;
} catch (NoSuchChangeException e) { } catch (NoSuchChangeException | OrmException | IOException
throw new MergeException("Cannot rebase " + n.name(), e); | InvalidChangeOperationException e) {
} catch (OrmException e) {
throw new MergeException("Cannot rebase " + n.name(), e);
} catch (IOException e) {
throw new MergeException("Cannot rebase " + n.name(), e);
} catch (InvalidChangeOperationException e) {
throw new MergeException("Cannot rebase " + n.name(), e); throw new MergeException("Cannot rebase " + n.name(), e);
} }
} }

View File

@ -22,9 +22,7 @@ import com.google.gerrit.reviewdb.server.ReviewDb;
import com.google.gerrit.server.ApprovalsUtil; import com.google.gerrit.server.ApprovalsUtil;
import com.google.gerrit.server.IdentifiedUser; import com.google.gerrit.server.IdentifiedUser;
import com.google.gerrit.server.index.ChangeIndexer; import com.google.gerrit.server.index.ChangeIndexer;
import com.google.gerrit.server.project.ChangeControl;
import com.google.gerrit.server.notedb.ChangeNotes;
import com.google.gerrit.server.notedb.ChangeUpdate;
import org.eclipse.jgit.lib.ObjectInserter; import org.eclipse.jgit.lib.ObjectInserter;
import org.eclipse.jgit.lib.PersonIdent; import org.eclipse.jgit.lib.PersonIdent;
@ -52,8 +50,7 @@ public abstract class SubmitStrategy {
protected final IdentifiedUser.GenericFactory identifiedUserFactory; protected final IdentifiedUser.GenericFactory identifiedUserFactory;
protected final PersonIdent myIdent; protected final PersonIdent myIdent;
protected final ReviewDb db; protected final ReviewDb db;
protected final ChangeNotes.Factory notesFactory; protected final ChangeControl.GenericFactory changeControlFactory;
protected final ChangeUpdate.Factory updateFactory;
protected final Repository repo; protected final Repository repo;
protected final RevWalk rw; protected final RevWalk rw;
@ -68,17 +65,15 @@ public abstract class SubmitStrategy {
Arguments(final IdentifiedUser.GenericFactory identifiedUserFactory, Arguments(final IdentifiedUser.GenericFactory identifiedUserFactory,
final PersonIdent myIdent, final ReviewDb db, final PersonIdent myIdent, final ReviewDb db,
final ChangeNotes.Factory notesFactory, final ChangeControl.GenericFactory changeControlFactory,
final ChangeUpdate.Factory updateFactory, final Repository repo, final Repository repo, final RevWalk rw, final ObjectInserter inserter,
final RevWalk rw, final ObjectInserter inserter,
final RevFlag canMergeFlag, final Set<RevCommit> alreadyAccepted, final RevFlag canMergeFlag, final Set<RevCommit> alreadyAccepted,
final Branch.NameKey destBranch, final ApprovalsUtil approvalsUtil, final Branch.NameKey destBranch, final ApprovalsUtil approvalsUtil,
final MergeUtil mergeUtil, final ChangeIndexer indexer) { final MergeUtil mergeUtil, final ChangeIndexer indexer) {
this.identifiedUserFactory = identifiedUserFactory; this.identifiedUserFactory = identifiedUserFactory;
this.myIdent = myIdent; this.myIdent = myIdent;
this.db = db; this.db = db;
this.notesFactory = notesFactory; this.changeControlFactory = changeControlFactory;
this.updateFactory = updateFactory;
this.repo = repo; this.repo = repo;
this.rw = rw; this.rw = rw;

View File

@ -23,9 +23,8 @@ import com.google.gerrit.server.IdentifiedUser;
import com.google.gerrit.server.changedetail.RebaseChange; import com.google.gerrit.server.changedetail.RebaseChange;
import com.google.gerrit.server.extensions.events.GitReferenceUpdated; import com.google.gerrit.server.extensions.events.GitReferenceUpdated;
import com.google.gerrit.server.index.ChangeIndexer; import com.google.gerrit.server.index.ChangeIndexer;
import com.google.gerrit.server.notedb.ChangeNotes;
import com.google.gerrit.server.notedb.ChangeUpdate;
import com.google.gerrit.server.patch.PatchSetInfoFactory; import com.google.gerrit.server.patch.PatchSetInfoFactory;
import com.google.gerrit.server.project.ChangeControl;
import com.google.gerrit.server.project.NoSuchProjectException; import com.google.gerrit.server.project.NoSuchProjectException;
import com.google.gerrit.server.project.ProjectCache; import com.google.gerrit.server.project.ProjectCache;
import com.google.gerrit.server.project.ProjectState; import com.google.gerrit.server.project.ProjectState;
@ -49,8 +48,7 @@ public class SubmitStrategyFactory {
private final IdentifiedUser.GenericFactory identifiedUserFactory; private final IdentifiedUser.GenericFactory identifiedUserFactory;
private final PersonIdent myIdent; private final PersonIdent myIdent;
private final ChangeNotes.Factory notesFactory; private final ChangeControl.GenericFactory changeControlFactory;
private final ChangeUpdate.Factory updateFactory;
private final PatchSetInfoFactory patchSetInfoFactory; private final PatchSetInfoFactory patchSetInfoFactory;
private final GitReferenceUpdated gitRefUpdated; private final GitReferenceUpdated gitRefUpdated;
private final RebaseChange rebaseChange; private final RebaseChange rebaseChange;
@ -63,8 +61,7 @@ public class SubmitStrategyFactory {
SubmitStrategyFactory( SubmitStrategyFactory(
final IdentifiedUser.GenericFactory identifiedUserFactory, final IdentifiedUser.GenericFactory identifiedUserFactory,
@GerritPersonIdent final PersonIdent myIdent, @GerritPersonIdent final PersonIdent myIdent,
final ChangeNotes.Factory notesFactory, final ChangeControl.GenericFactory changeControlFactory,
final ChangeUpdate.Factory updateFactory,
final PatchSetInfoFactory patchSetInfoFactory, final PatchSetInfoFactory patchSetInfoFactory,
final GitReferenceUpdated gitRefUpdated, final RebaseChange rebaseChange, final GitReferenceUpdated gitRefUpdated, final RebaseChange rebaseChange,
final ProjectCache projectCache, final ProjectCache projectCache,
@ -73,8 +70,7 @@ public class SubmitStrategyFactory {
final ChangeIndexer indexer) { final ChangeIndexer indexer) {
this.identifiedUserFactory = identifiedUserFactory; this.identifiedUserFactory = identifiedUserFactory;
this.myIdent = myIdent; this.myIdent = myIdent;
this.notesFactory = notesFactory; this.changeControlFactory = changeControlFactory;
this.updateFactory = updateFactory;
this.patchSetInfoFactory = patchSetInfoFactory; this.patchSetInfoFactory = patchSetInfoFactory;
this.gitRefUpdated = gitRefUpdated; this.gitRefUpdated = gitRefUpdated;
this.rebaseChange = rebaseChange; this.rebaseChange = rebaseChange;
@ -92,7 +88,7 @@ public class SubmitStrategyFactory {
ProjectState project = getProject(destBranch); ProjectState project = getProject(destBranch);
final SubmitStrategy.Arguments args = final SubmitStrategy.Arguments args =
new SubmitStrategy.Arguments(identifiedUserFactory, myIdent, db, new SubmitStrategy.Arguments(identifiedUserFactory, myIdent, db,
notesFactory, updateFactory, repo, rw, inserter, canMergeFlag, changeControlFactory, repo, rw, inserter, canMergeFlag,
alreadyAccepted, destBranch,approvalsUtil, alreadyAccepted, destBranch,approvalsUtil,
mergeUtilFactory.create(project), indexer); mergeUtilFactory.create(project), indexer);
switch (submitType) { switch (submitType) {
@ -105,7 +101,8 @@ public class SubmitStrategyFactory {
case MERGE_IF_NECESSARY: case MERGE_IF_NECESSARY:
return new MergeIfNecessary(args); return new MergeIfNecessary(args);
case REBASE_IF_NECESSARY: case REBASE_IF_NECESSARY:
return new RebaseIfNecessary(args, rebaseChange, myIdent); return new RebaseIfNecessary(
args, patchSetInfoFactory, rebaseChange, myIdent);
default: default:
final String errorMsg = "No submit strategy for: " + submitType; final String errorMsg = "No submit strategy for: " + submitType;
log.error(errorMsg); log.error(errorMsg);

View File

@ -125,7 +125,7 @@ public class MergeValidators {
} else { } else {
if (!oldParent.equals(newParent)) { if (!oldParent.equals(newParent)) {
PatchSetApproval psa = PatchSetApproval psa =
approvalsUtil.getSubmitter(db, commit.notes, patchSetId); approvalsUtil.getSubmitter(db, commit.notes(), patchSetId);
if (psa == null) { if (psa == null) {
throw new MergeValidationException(CommitMergeStatus. throw new MergeValidationException(CommitMergeStatus.
SETTING_PARENT_PROJECT_ONLY_ALLOWED_BY_ADMIN); SETTING_PARENT_PROJECT_ONLY_ALLOWED_BY_ADMIN);

View File

@ -30,8 +30,6 @@ import com.google.gerrit.reviewdb.client.SubmoduleSubscription;
import com.google.gerrit.reviewdb.server.ReviewDb; import com.google.gerrit.reviewdb.server.ReviewDb;
import com.google.gerrit.reviewdb.server.SubmoduleSubscriptionAccess; import com.google.gerrit.reviewdb.server.SubmoduleSubscriptionAccess;
import com.google.gerrit.server.extensions.events.GitReferenceUpdated; import com.google.gerrit.server.extensions.events.GitReferenceUpdated;
import com.google.gerrit.server.notedb.ChangeNotes;
import com.google.gerrit.server.util.TimeUtil; import com.google.gerrit.server.util.TimeUtil;
import com.google.gwtorm.client.KeyUtil; import com.google.gwtorm.client.KeyUtil;
import com.google.gwtorm.server.ListResultSet; import com.google.gwtorm.server.ListResultSet;
@ -81,7 +79,6 @@ public class SubmoduleOpTest extends LocalDiskRepositoryTestCase {
private Provider<String> urlProvider; private Provider<String> urlProvider;
private GitRepositoryManager repoManager; private GitRepositoryManager repoManager;
private GitReferenceUpdated gitRefUpdated; private GitReferenceUpdated gitRefUpdated;
private ChangeNotes.Factory notesFactory;
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
@Override @Override
@ -95,7 +92,6 @@ public class SubmoduleOpTest extends LocalDiskRepositoryTestCase {
urlProvider = createStrictMock(Provider.class); urlProvider = createStrictMock(Provider.class);
repoManager = createStrictMock(GitRepositoryManager.class); repoManager = createStrictMock(GitRepositoryManager.class);
gitRefUpdated = createStrictMock(GitReferenceUpdated.class); gitRefUpdated = createStrictMock(GitReferenceUpdated.class);
notesFactory = new ChangeNotes.Factory(repoManager);
} }
private void doReplay() { private void doReplay() {
@ -616,11 +612,10 @@ public class SubmoduleOpTest extends LocalDiskRepositoryTestCase {
final Change submittedChange = new Change( final Change submittedChange = new Change(
new Change.Key(sourceMergeTip.toObjectId().getName()), new Change.Id(1), new Change.Key(sourceMergeTip.toObjectId().getName()), new Change.Id(1),
new Account.Id(1), sourceBranchNameKey, TimeUtil.nowTs()); new Account.Id(1), sourceBranchNameKey, TimeUtil.nowTs());
codeReviewCommit.notes = notesFactory.create(submittedChange);
final Map<Change.Id, CodeReviewCommit> mergedCommits = final Map<Change.Id, CodeReviewCommit> mergedCommits =
new HashMap<Change.Id, CodeReviewCommit>(); new HashMap<Change.Id, CodeReviewCommit>();
mergedCommits.put(codeReviewCommit.notes.getChangeId(), codeReviewCommit); mergedCommits.put(submittedChange.getId(), codeReviewCommit);
final List<Change> submitted = new ArrayList<Change>(); final List<Change> submitted = new ArrayList<Change>();
submitted.add(submittedChange); submitted.add(submittedChange);
@ -720,11 +715,10 @@ public class SubmoduleOpTest extends LocalDiskRepositoryTestCase {
final Change submittedChange = new Change( final Change submittedChange = new Change(
new Change.Key(sourceMergeTip.toObjectId().getName()), new Change.Id(1), new Change.Key(sourceMergeTip.toObjectId().getName()), new Change.Id(1),
new Account.Id(1), sourceBranchNameKey, TimeUtil.nowTs()); new Account.Id(1), sourceBranchNameKey, TimeUtil.nowTs());
codeReviewCommit.notes = notesFactory.create(submittedChange);
final Map<Change.Id, CodeReviewCommit> mergedCommits = final Map<Change.Id, CodeReviewCommit> mergedCommits =
new HashMap<Change.Id, CodeReviewCommit>(); new HashMap<Change.Id, CodeReviewCommit>();
mergedCommits.put(codeReviewCommit.notes.getChangeId(), codeReviewCommit); mergedCommits.put(submittedChange.getId(), codeReviewCommit);
final List<Change> submitted = new ArrayList<Change>(); final List<Change> submitted = new ArrayList<Change>();
submitted.add(submittedChange); submitted.add(submittedChange);