Added copyAllScoresIfNoChange
Covers the case when nothing has changed except the commit of the rebased patch set. This is possible when a patch set is rebased on target branch. With this patch, when PS1 is rebased (without modification) to PS2 the Verified+1 and Code-Review+2 will be copied since PS1 and PS2 are effectively the same change with different commits. ----- (B) ----- (B+M) ----- (B+M-M) \ \ ----- (PS1) ----- (PS2) Change-Id: I6a8ebd3c83ca6167cfc826267a057a871c752ff6
This commit is contained in:
parent
f62a233cc4
commit
ae4768654e
@ -50,8 +50,9 @@ kind:: change kind represents the kind of change uploaded, also represented in l
|
|||||||
|
|
||||||
TRIVIAL_REBASE;; Conflict-free merge between the new parent and the prior patch set.
|
TRIVIAL_REBASE;; Conflict-free merge between the new parent and the prior patch set.
|
||||||
|
|
||||||
NO_CODE_CHANGE;; No code changed; same tree and same parents.
|
NO_CODE_CHANGE;; No code changed; same tree and same parent tree.
|
||||||
|
|
||||||
|
NO_CHANGE;; No changes; same commit message, same tree and same parent tree.
|
||||||
|
|
||||||
=== draft-published
|
=== draft-published
|
||||||
|
|
||||||
|
@ -241,19 +241,33 @@ as trivial rebase if the commit message is the same as in the previous
|
|||||||
patch set and if it has the same code delta as the previous patch set.
|
patch set and if it has the same code delta as the previous patch set.
|
||||||
This is the case if the change was rebased onto a different parent.
|
This is the case if the change was rebased onto a different parent.
|
||||||
This can be used to enable sticky approvals, reducing turn-around for
|
This can be used to enable sticky approvals, reducing turn-around for
|
||||||
trivial rebases prior to submitting a change. Defaults to false.
|
trivial rebases prior to submitting a change.
|
||||||
|
It is recommended to enable this for the Code-Review label.
|
||||||
|
Defaults to false.
|
||||||
|
|
||||||
[[label_copyAllScoresIfNoCodeChange]]
|
[[label_copyAllScoresIfNoCodeChange]]
|
||||||
=== `label.Label-Name.copyAllScoresIfNoCodeChange`
|
=== `label.Label-Name.copyAllScoresIfNoCodeChange`
|
||||||
|
|
||||||
If true, all scores for the label are copied forward when a new patch
|
If true, all scores for the label are copied forward when a new patch
|
||||||
set is uploaded that has the same parent commit as the previous patch
|
set is uploaded that has the same parent tree as the previous patch
|
||||||
set and the same code delta as the previous patch set. This means only
|
set and the same code delta as the previous patch set. This means only
|
||||||
the commit message is different. This can be used to enable sticky
|
the commit message is different. This can be used to enable sticky
|
||||||
approvals on labels that only depend on the code, reducing turn-around
|
approvals on labels that only depend on the code, reducing turn-around
|
||||||
if only the commit message is changed prior to submitting a change.
|
if only the commit message is changed prior to submitting a change.
|
||||||
|
It is recommended to enable this for the Verified label if enabled.
|
||||||
Defaults to false.
|
Defaults to false.
|
||||||
|
|
||||||
|
[[label_copyAllScoresIfNoChange]]
|
||||||
|
=== `label.Label-Name.copyAllScoresIfNoChange`
|
||||||
|
|
||||||
|
If true, all scores for the label are copied forward when a new patch
|
||||||
|
set is uploaded that has the same parent tree, code delta, and commit
|
||||||
|
message as the previous patch set. This means that only the patch
|
||||||
|
set SHA1 is different. This can be used to enable sticky
|
||||||
|
approvals, reducing turn-around for this special case.
|
||||||
|
It is recommended to leave this enabled for both Verified and
|
||||||
|
Code-Review labels. Defaults to true.
|
||||||
|
|
||||||
[[label_canOverride]]
|
[[label_canOverride]]
|
||||||
=== `label.Label-Name.canOverride`
|
=== `label.Label-Name.canOverride`
|
||||||
|
|
||||||
|
@ -119,7 +119,9 @@ kind:: Kind of change uploaded.
|
|||||||
|
|
||||||
TRIVIAL_REBASE;; Conflict-free merge between the new parent and the prior patch set.
|
TRIVIAL_REBASE;; Conflict-free merge between the new parent and the prior patch set.
|
||||||
|
|
||||||
NO_CODE_CHANGE;; No code changed; same tree and same parents.
|
NO_CODE_CHANGE;; No code changed; same tree and same parent tree.
|
||||||
|
|
||||||
|
NO_CHANGE;; No changes; same commit message, same tree and same parent tree.
|
||||||
|
|
||||||
approvals:: The <<approval,approval attribute>> granted.
|
approvals:: The <<approval,approval attribute>> granted.
|
||||||
|
|
||||||
|
@ -94,6 +94,7 @@ public class LabelType {
|
|||||||
protected boolean copyMaxScore;
|
protected boolean copyMaxScore;
|
||||||
protected boolean copyAllScoresOnTrivialRebase;
|
protected boolean copyAllScoresOnTrivialRebase;
|
||||||
protected boolean copyAllScoresIfNoCodeChange;
|
protected boolean copyAllScoresIfNoCodeChange;
|
||||||
|
protected boolean copyAllScoresIfNoChange;
|
||||||
protected short defaultValue;
|
protected short defaultValue;
|
||||||
|
|
||||||
protected List<LabelValue> values;
|
protected List<LabelValue> values;
|
||||||
@ -219,6 +220,14 @@ public class LabelType {
|
|||||||
this.copyAllScoresIfNoCodeChange = copyAllScoresIfNoCodeChange;
|
this.copyAllScoresIfNoCodeChange = copyAllScoresIfNoCodeChange;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isCopyAllScoresIfNoChange() {
|
||||||
|
return copyAllScoresIfNoChange;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCopyAllScoresIfNoChange(boolean copyAllScoresIfNoChange) {
|
||||||
|
this.copyAllScoresIfNoChange = copyAllScoresIfNoChange;
|
||||||
|
}
|
||||||
|
|
||||||
public boolean isMaxNegative(PatchSetApproval ca) {
|
public boolean isMaxNegative(PatchSetApproval ca) {
|
||||||
return maxNegative == ca.getValue();
|
return maxNegative == ca.getValue();
|
||||||
}
|
}
|
||||||
|
@ -16,6 +16,7 @@ package com.google.gerrit.server;
|
|||||||
|
|
||||||
import static com.google.common.base.Preconditions.checkArgument;
|
import static com.google.common.base.Preconditions.checkArgument;
|
||||||
import static com.google.gerrit.server.change.ChangeKind.NO_CODE_CHANGE;
|
import static com.google.gerrit.server.change.ChangeKind.NO_CODE_CHANGE;
|
||||||
|
import static com.google.gerrit.server.change.ChangeKind.NO_CHANGE;
|
||||||
import static com.google.gerrit.server.change.ChangeKind.TRIVIAL_REBASE;
|
import static com.google.gerrit.server.change.ChangeKind.TRIVIAL_REBASE;
|
||||||
|
|
||||||
import com.google.common.collect.HashBasedTable;
|
import com.google.common.collect.HashBasedTable;
|
||||||
@ -164,7 +165,8 @@ public class ApprovalCopier {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return (type.isCopyAllScoresOnTrivialRebase() && kind == TRIVIAL_REBASE)
|
return (type.isCopyAllScoresOnTrivialRebase() && kind == TRIVIAL_REBASE)
|
||||||
|| (type.isCopyAllScoresIfNoCodeChange() && kind == NO_CODE_CHANGE);
|
|| (type.isCopyAllScoresIfNoCodeChange() && kind == NO_CODE_CHANGE)
|
||||||
|
|| (type.isCopyAllScoresIfNoChange() && kind == NO_CHANGE);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static PatchSetApproval copy(PatchSetApproval src, PatchSet.Id psId) {
|
private static PatchSetApproval copy(PatchSetApproval src, PatchSet.Id psId) {
|
||||||
|
@ -22,6 +22,9 @@ public enum ChangeKind {
|
|||||||
/** Conflict-free merge between the new parent and the prior patch set. */
|
/** Conflict-free merge between the new parent and the prior patch set. */
|
||||||
TRIVIAL_REBASE,
|
TRIVIAL_REBASE,
|
||||||
|
|
||||||
/** Same tree and same parents. */
|
/** Same tree and same parent tree. */
|
||||||
NO_CODE_CHANGE;
|
NO_CODE_CHANGE,
|
||||||
|
|
||||||
|
/** Same tree, parent tree, same commit message. */
|
||||||
|
NO_CHANGE;
|
||||||
}
|
}
|
||||||
|
@ -197,23 +197,22 @@ public class ChangeKindCacheImpl implements ChangeKindCache {
|
|||||||
walk.parseBody(next);
|
walk.parseBody(next);
|
||||||
|
|
||||||
if (!next.getFullMessage().equals(prior.getFullMessage())) {
|
if (!next.getFullMessage().equals(prior.getFullMessage())) {
|
||||||
if (next.getTree() == prior.getTree() && isSameParents(prior, next)) {
|
if (isSameDeltaAndTree(prior, next)) {
|
||||||
return ChangeKind.NO_CODE_CHANGE;
|
return ChangeKind.NO_CODE_CHANGE;
|
||||||
} else {
|
} else {
|
||||||
return ChangeKind.REWORK;
|
return ChangeKind.REWORK;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (isSameDeltaAndTree(prior, next)) {
|
||||||
|
return ChangeKind.NO_CHANGE;
|
||||||
|
}
|
||||||
|
|
||||||
if (prior.getParentCount() != 1 || next.getParentCount() != 1) {
|
if (prior.getParentCount() != 1 || next.getParentCount() != 1) {
|
||||||
// Trivial rebases done by machine only work well on 1 parent.
|
// Trivial rebases done by machine only work well on 1 parent.
|
||||||
return ChangeKind.REWORK;
|
return ChangeKind.REWORK;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (next.getTree() == prior.getTree() &&
|
|
||||||
isSameParents(prior, next)) {
|
|
||||||
return ChangeKind.TRIVIAL_REBASE;
|
|
||||||
}
|
|
||||||
|
|
||||||
// A trivial rebase can be detected by looking for the next commit
|
// A trivial rebase can be detected by looking for the next commit
|
||||||
// having the same tree as would exist when the prior commit is
|
// having the same tree as would exist when the prior commit is
|
||||||
// cherry-picked onto the next commit's new first parent.
|
// cherry-picked onto the next commit's new first parent.
|
||||||
@ -232,13 +231,25 @@ public class ChangeKindCacheImpl implements ChangeKindCache {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean isSameParents(RevCommit prior, RevCommit next) {
|
private static boolean isSameDeltaAndTree(RevCommit prior, RevCommit next) {
|
||||||
|
if (next.getTree() != prior.getTree()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (prior.getParentCount() != next.getParentCount()) {
|
if (prior.getParentCount() != next.getParentCount()) {
|
||||||
return false;
|
return false;
|
||||||
} else if (prior.getParentCount() == 0) {
|
} else if (prior.getParentCount() == 0) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return prior.getParent(0).equals(next.getParent(0));
|
|
||||||
|
// Make sure that the prior/next delta is the same - not just the tree.
|
||||||
|
// This is done by making sure that the parent trees are equal.
|
||||||
|
for (int i = 0; i < prior.getParentCount(); i++) {
|
||||||
|
if (next.getParent(i).getTree() != prior.getParent(i).getTree()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -134,7 +134,8 @@ public class ProjectConfig extends VersionedMetaData implements ValidationError.
|
|||||||
private static final String KEY_COPY_MIN_SCORE = "copyMinScore";
|
private static final String KEY_COPY_MIN_SCORE = "copyMinScore";
|
||||||
private static final String KEY_COPY_MAX_SCORE = "copyMaxScore";
|
private static final String KEY_COPY_MAX_SCORE = "copyMaxScore";
|
||||||
private static final String KEY_COPY_ALL_SCORES_ON_TRIVIAL_REBASE = "copyAllScoresOnTrivialRebase";
|
private static final String KEY_COPY_ALL_SCORES_ON_TRIVIAL_REBASE = "copyAllScoresOnTrivialRebase";
|
||||||
private static final String KEY_COPY_ALL_SCORES_IF_NO_CHANGE = "copyAllScoresIfNoCodeChange";
|
private static final String KEY_COPY_ALL_SCORES_IF_NO_CODE_CHANGE = "copyAllScoresIfNoCodeChange";
|
||||||
|
private static final String KEY_COPY_ALL_SCORES_IF_NO_CHANGE = "copyAllScoresIfNoChange";
|
||||||
private static final String KEY_VALUE = "value";
|
private static final String KEY_VALUE = "value";
|
||||||
private static final String KEY_CAN_OVERRIDE = "canOverride";
|
private static final String KEY_CAN_OVERRIDE = "canOverride";
|
||||||
private static final String KEY_Branch = "branch";
|
private static final String KEY_Branch = "branch";
|
||||||
@ -696,7 +697,9 @@ public class ProjectConfig extends VersionedMetaData implements ValidationError.
|
|||||||
label.setCopyAllScoresOnTrivialRebase(
|
label.setCopyAllScoresOnTrivialRebase(
|
||||||
rc.getBoolean(LABEL, name, KEY_COPY_ALL_SCORES_ON_TRIVIAL_REBASE, false));
|
rc.getBoolean(LABEL, name, KEY_COPY_ALL_SCORES_ON_TRIVIAL_REBASE, false));
|
||||||
label.setCopyAllScoresIfNoCodeChange(
|
label.setCopyAllScoresIfNoCodeChange(
|
||||||
rc.getBoolean(LABEL, name, KEY_COPY_ALL_SCORES_IF_NO_CHANGE, false));
|
rc.getBoolean(LABEL, name, KEY_COPY_ALL_SCORES_IF_NO_CODE_CHANGE, false));
|
||||||
|
label.setCopyAllScoresIfNoChange(
|
||||||
|
rc.getBoolean(LABEL, name, KEY_COPY_ALL_SCORES_IF_NO_CHANGE, true));
|
||||||
label.setCanOverride(
|
label.setCanOverride(
|
||||||
rc.getBoolean(LABEL, name, KEY_CAN_OVERRIDE, true));
|
rc.getBoolean(LABEL, name, KEY_CAN_OVERRIDE, true));
|
||||||
label.setRefPatterns(getStringListOrNull(rc, LABEL, name, KEY_Branch));
|
label.setRefPatterns(getStringListOrNull(rc, LABEL, name, KEY_Branch));
|
||||||
@ -1047,6 +1050,11 @@ public class ProjectConfig extends VersionedMetaData implements ValidationError.
|
|||||||
rc.unset(LABEL, name, KEY_COPY_ALL_SCORES_ON_TRIVIAL_REBASE);
|
rc.unset(LABEL, name, KEY_COPY_ALL_SCORES_ON_TRIVIAL_REBASE);
|
||||||
}
|
}
|
||||||
if (label.isCopyAllScoresIfNoCodeChange()) {
|
if (label.isCopyAllScoresIfNoCodeChange()) {
|
||||||
|
rc.setBoolean(LABEL, name, KEY_COPY_ALL_SCORES_IF_NO_CODE_CHANGE, true);
|
||||||
|
} else {
|
||||||
|
rc.unset(LABEL, name, KEY_COPY_ALL_SCORES_IF_NO_CODE_CHANGE);
|
||||||
|
}
|
||||||
|
if (label.isCopyAllScoresIfNoChange()) {
|
||||||
rc.setBoolean(LABEL, name, KEY_COPY_ALL_SCORES_IF_NO_CHANGE, true);
|
rc.setBoolean(LABEL, name, KEY_COPY_ALL_SCORES_IF_NO_CHANGE, true);
|
||||||
} else {
|
} else {
|
||||||
rc.unset(LABEL, name, KEY_COPY_ALL_SCORES_IF_NO_CHANGE);
|
rc.unset(LABEL, name, KEY_COPY_ALL_SCORES_IF_NO_CHANGE);
|
||||||
|
@ -2072,6 +2072,7 @@ public class ReceiveCommits {
|
|||||||
String message = "Uploaded patch set " + newPatchSet.getPatchSetId();
|
String message = "Uploaded patch set " + newPatchSet.getPatchSetId();
|
||||||
switch (changeKind) {
|
switch (changeKind) {
|
||||||
case TRIVIAL_REBASE:
|
case TRIVIAL_REBASE:
|
||||||
|
case NO_CHANGE:
|
||||||
message += ": Patch Set " + priorPatchSet.get() + " was rebased";
|
message += ": Patch Set " + priorPatchSet.get() + " was rebased";
|
||||||
break;
|
break;
|
||||||
case NO_CODE_CHANGE:
|
case NO_CODE_CHANGE:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user