Compare incoming change-id to target change
When pushing to an existing change (for example to refs/changes or editing a change in the UI) the change-id in the message footers must not differ from the change-id of the target change. This change will add the target change (if any, else null) to the ChangeIdValidator, and check that the change-id footer is the same as the key of the target change. Change-Id: I92cdd3af04ac6e6548630483041c342509bb1224
This commit is contained in:
@@ -19,6 +19,7 @@ import static com.google.gerrit.reviewdb.client.RefNames.REFS_CHANGES;
|
||||
import static com.google.gerrit.reviewdb.client.RefNames.REFS_CONFIG;
|
||||
import static java.util.stream.Collectors.toList;
|
||||
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import com.google.common.base.CharMatcher;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.gerrit.common.FooterConstants;
|
||||
@@ -30,6 +31,8 @@ import com.google.gerrit.extensions.restapi.AuthException;
|
||||
import com.google.gerrit.reviewdb.client.Account;
|
||||
import com.google.gerrit.reviewdb.client.BooleanProjectConfig;
|
||||
import com.google.gerrit.reviewdb.client.Branch;
|
||||
import com.google.gerrit.reviewdb.client.Branch.NameKey;
|
||||
import com.google.gerrit.reviewdb.client.Change;
|
||||
import com.google.gerrit.reviewdb.client.Project;
|
||||
import com.google.gerrit.reviewdb.client.RefNames;
|
||||
import com.google.gerrit.reviewdb.client.RevId;
|
||||
@@ -46,6 +49,7 @@ import com.google.gerrit.server.git.GitRepositoryManager;
|
||||
import com.google.gerrit.server.git.ProjectConfig;
|
||||
import com.google.gerrit.server.git.ValidationError;
|
||||
import com.google.gerrit.server.permissions.PermissionBackend;
|
||||
import com.google.gerrit.server.permissions.PermissionBackend.ForRef;
|
||||
import com.google.gerrit.server.permissions.PermissionBackendException;
|
||||
import com.google.gerrit.server.permissions.RefPermission;
|
||||
import com.google.gerrit.server.project.ProjectCache;
|
||||
@@ -125,7 +129,8 @@ public class CommitValidators {
|
||||
IdentifiedUser user,
|
||||
SshInfo sshInfo,
|
||||
Repository repo,
|
||||
RevWalk rw)
|
||||
RevWalk rw,
|
||||
@Nullable Change change)
|
||||
throws IOException {
|
||||
NoteMap rejectCommits = BanCommit.loadRejectCommitsMap(repo, rw);
|
||||
ProjectState projectState = projectCache.checkedGet(branch.getParentKey());
|
||||
@@ -138,7 +143,12 @@ public class CommitValidators {
|
||||
new CommitterUploaderValidator(user, perm, canonicalWebUrl),
|
||||
new SignedOffByValidator(user, perm, projectState),
|
||||
new ChangeIdValidator(
|
||||
projectState, user, canonicalWebUrl, installCommitMsgHookCommand, sshInfo),
|
||||
projectState,
|
||||
user,
|
||||
canonicalWebUrl,
|
||||
installCommitMsgHookCommand,
|
||||
sshInfo,
|
||||
change),
|
||||
new ConfigValidator(branch, user, rw, allUsers, allProjects),
|
||||
new BannedCommitsValidator(rejectCommits),
|
||||
new PluginCommitValidationListener(pluginValidators),
|
||||
@@ -148,11 +158,12 @@ public class CommitValidators {
|
||||
}
|
||||
|
||||
public CommitValidators forGerritCommits(
|
||||
PermissionBackend.ForRef perm,
|
||||
Branch.NameKey branch,
|
||||
ForRef perm,
|
||||
NameKey branch,
|
||||
IdentifiedUser user,
|
||||
SshInfo sshInfo,
|
||||
RevWalk rw)
|
||||
RevWalk rw,
|
||||
@Nullable Change change)
|
||||
throws IOException {
|
||||
ProjectState projectState = projectCache.checkedGet(branch.getParentKey());
|
||||
return new CommitValidators(
|
||||
@@ -163,7 +174,12 @@ public class CommitValidators {
|
||||
new AuthorUploaderValidator(user, perm, canonicalWebUrl),
|
||||
new SignedOffByValidator(user, perm, projectCache.checkedGet(branch.getParentKey())),
|
||||
new ChangeIdValidator(
|
||||
projectState, user, canonicalWebUrl, installCommitMsgHookCommand, sshInfo),
|
||||
projectState,
|
||||
user,
|
||||
canonicalWebUrl,
|
||||
installCommitMsgHookCommand,
|
||||
sshInfo,
|
||||
change),
|
||||
new ConfigValidator(branch, user, rw, allUsers, allProjects),
|
||||
new PluginCommitValidationListener(pluginValidators),
|
||||
new ExternalIdUpdateListener(allUsers, externalIdsConsistencyChecker),
|
||||
@@ -231,6 +247,15 @@ public class CommitValidators {
|
||||
"[%s] invalid "
|
||||
+ FooterConstants.CHANGE_ID.getName()
|
||||
+ " line format in commit message footer";
|
||||
|
||||
@VisibleForTesting
|
||||
public static final String CHANGE_ID_MISMATCH_MSG =
|
||||
"[%s] "
|
||||
+ FooterConstants.CHANGE_ID.getName()
|
||||
+ " in commit message footer does not match"
|
||||
+ FooterConstants.CHANGE_ID.getName()
|
||||
+ " of target change";
|
||||
|
||||
private static final Pattern CHANGE_ID = Pattern.compile(CHANGE_ID_PATTERN);
|
||||
|
||||
private final ProjectState projectState;
|
||||
@@ -238,18 +263,21 @@ public class CommitValidators {
|
||||
private final String installCommitMsgHookCommand;
|
||||
private final SshInfo sshInfo;
|
||||
private final IdentifiedUser user;
|
||||
private final Change change;
|
||||
|
||||
public ChangeIdValidator(
|
||||
ProjectState projectState,
|
||||
IdentifiedUser user,
|
||||
String canonicalWebUrl,
|
||||
String installCommitMsgHookCommand,
|
||||
SshInfo sshInfo) {
|
||||
SshInfo sshInfo,
|
||||
Change change) {
|
||||
this.projectState = projectState;
|
||||
this.canonicalWebUrl = canonicalWebUrl;
|
||||
this.installCommitMsgHookCommand = installCommitMsgHookCommand;
|
||||
this.sshInfo = sshInfo;
|
||||
this.user = user;
|
||||
this.change = change;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -289,7 +317,12 @@ public class CommitValidators {
|
||||
messages.add(getMissingChangeIdErrorMsg(errMsg, receiveEvent.commit));
|
||||
throw new CommitValidationException(errMsg, messages);
|
||||
}
|
||||
if (change != null && !v.equals(change.getKey().get())) {
|
||||
String errMsg = String.format(CHANGE_ID_MISMATCH_MSG, sha1);
|
||||
throw new CommitValidationException(errMsg);
|
||||
}
|
||||
}
|
||||
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user