Add 'CherryPickOf' field for a change
After a change is created or updated using the 'cherry-pick' functionality, this field will contain the source change number and the patchset. Having this field helps us identify changes where actual dev time was spent on by filtering out propagated changes. This is especially useful for organizations wanting to generate cost metrics. Change-Id: I782a56aa52c52670ec74fabb713fe47ecba24de1
This commit is contained in:

committed by
Kaushik Lingarkar

parent
8b457aeb17
commit
4a711eda84
@@ -42,6 +42,7 @@ import com.google.gerrit.server.ReviewerSet;
|
||||
import com.google.gerrit.server.change.ChangeInserter;
|
||||
import com.google.gerrit.server.change.NotifyResolver;
|
||||
import com.google.gerrit.server.change.PatchSetInserter;
|
||||
import com.google.gerrit.server.change.SetCherryPickOp;
|
||||
import com.google.gerrit.server.git.CodeReviewCommit;
|
||||
import com.google.gerrit.server.git.CodeReviewCommit.CodeReviewRevWalk;
|
||||
import com.google.gerrit.server.git.GitRepositoryManager;
|
||||
@@ -102,6 +103,7 @@ public class CherryPickChange {
|
||||
private final Provider<IdentifiedUser> user;
|
||||
private final ChangeInserter.Factory changeInserterFactory;
|
||||
private final PatchSetInserter.Factory patchSetInserterFactory;
|
||||
private final SetCherryPickOp.Factory setCherryPickOfFactory;
|
||||
private final MergeUtil.Factory mergeUtilFactory;
|
||||
private final ChangeNotes.Factory changeNotesFactory;
|
||||
private final ProjectCache projectCache;
|
||||
@@ -117,6 +119,7 @@ public class CherryPickChange {
|
||||
Provider<IdentifiedUser> user,
|
||||
ChangeInserter.Factory changeInserterFactory,
|
||||
PatchSetInserter.Factory patchSetInserterFactory,
|
||||
SetCherryPickOp.Factory setCherryPickOfFactory,
|
||||
MergeUtil.Factory mergeUtilFactory,
|
||||
ChangeNotes.Factory changeNotesFactory,
|
||||
ProjectCache projectCache,
|
||||
@@ -129,6 +132,7 @@ public class CherryPickChange {
|
||||
this.user = user;
|
||||
this.changeInserterFactory = changeInserterFactory;
|
||||
this.patchSetInserterFactory = patchSetInserterFactory;
|
||||
this.setCherryPickOfFactory = setCherryPickOfFactory;
|
||||
this.mergeUtilFactory = mergeUtilFactory;
|
||||
this.changeNotesFactory = changeNotesFactory;
|
||||
this.projectCache = projectCache;
|
||||
@@ -374,7 +378,13 @@ public class CherryPickChange {
|
||||
dest.project(),
|
||||
destChanges.get(0).getId().get()));
|
||||
}
|
||||
changeId = insertPatchSet(bu, git, destChanges.get(0).notes(), cherryPickCommit);
|
||||
changeId =
|
||||
insertPatchSet(
|
||||
bu,
|
||||
git,
|
||||
destChanges.get(0).notes(),
|
||||
cherryPickCommit,
|
||||
sourceChange.currentPatchSetId());
|
||||
} else {
|
||||
// Change key not found on destination branch. We can create a new
|
||||
// change.
|
||||
@@ -457,13 +467,22 @@ public class CherryPickChange {
|
||||
}
|
||||
|
||||
private Change.Id insertPatchSet(
|
||||
BatchUpdate bu, Repository git, ChangeNotes destNotes, CodeReviewCommit cherryPickCommit)
|
||||
BatchUpdate bu,
|
||||
Repository git,
|
||||
ChangeNotes destNotes,
|
||||
CodeReviewCommit cherryPickCommit,
|
||||
PatchSet.Id sourcePatchSetId)
|
||||
throws IOException {
|
||||
Change destChange = destNotes.getChange();
|
||||
PatchSet.Id psId = ChangeUtil.nextPatchSetId(git, destChange.currentPatchSetId());
|
||||
PatchSetInserter inserter = patchSetInserterFactory.create(destNotes, psId, cherryPickCommit);
|
||||
inserter.setMessage("Uploaded patch set " + inserter.getPatchSetId().get() + ".");
|
||||
bu.addOp(destChange.getId(), inserter);
|
||||
if (destChange.getCherryPickOf() == null
|
||||
|| !destChange.getCherryPickOf().equals(sourcePatchSetId)) {
|
||||
SetCherryPickOp cherryPickOfUpdater = setCherryPickOfFactory.create(sourcePatchSetId);
|
||||
bu.addOp(destChange.getId(), cherryPickOfUpdater);
|
||||
}
|
||||
return destChange.getId();
|
||||
}
|
||||
|
||||
@@ -483,6 +502,7 @@ public class CherryPickChange {
|
||||
ChangeInserter ins = changeInserterFactory.create(changeId, cherryPickCommit, refName);
|
||||
ins.setRevertOf(revertOf);
|
||||
BranchNameKey sourceBranch = sourceChange == null ? null : sourceChange.getDest();
|
||||
PatchSet.Id sourcePatchSetId = sourceChange == null ? null : sourceChange.currentPatchSetId();
|
||||
ins.setMessage(
|
||||
revertOf == null
|
||||
? messageForDestinationChange(
|
||||
@@ -490,6 +510,7 @@ public class CherryPickChange {
|
||||
: "Uploaded patch set 1.") // For revert commits, the message should not include
|
||||
// cherry-pick information.
|
||||
.setTopic(topic)
|
||||
.setCherryPickOf(sourcePatchSetId)
|
||||
.setWorkInProgress(
|
||||
(sourceChange != null && sourceChange.isWorkInProgress())
|
||||
|| !cherryPickCommit.getFilesWithGitConflicts().isEmpty());
|
||||
|
@@ -40,6 +40,7 @@ import com.google.gerrit.server.change.PatchSetInserter;
|
||||
import com.google.gerrit.server.change.RebaseChangeOp;
|
||||
import com.google.gerrit.server.change.ReviewerResource;
|
||||
import com.google.gerrit.server.change.SetAssigneeOp;
|
||||
import com.google.gerrit.server.change.SetCherryPickOp;
|
||||
import com.google.gerrit.server.change.SetHashtagsOp;
|
||||
import com.google.gerrit.server.change.SetPrivateOp;
|
||||
import com.google.gerrit.server.change.WorkInProgressOp;
|
||||
@@ -201,6 +202,7 @@ public class Module extends RestApiModule {
|
||||
factory(RebaseChangeOp.Factory.class);
|
||||
factory(ReviewerResource.Factory.class);
|
||||
factory(SetAssigneeOp.Factory.class);
|
||||
factory(SetCherryPickOp.Factory.class);
|
||||
factory(SetHashtagsOp.Factory.class);
|
||||
factory(SetPrivateOp.Factory.class);
|
||||
factory(WorkInProgressOp.Factory.class);
|
||||
|
Reference in New Issue
Block a user