CreateNewChangeForAllNotInTarget: Fix working with change series
If a change is pushed that depends on an open change and both changes are targeted to the same destination branch, we don't want to recreate the base change for the same branch if the CreateNewChangeForAllNotInTarget project option is set to true. We also don't want to do any validation of the base change as it is not touched by the upload of a successor change. At the moment trying to push a change that depends on an open change of another user fails with "invalid committer" if the uploading user doesn't have the Forge Committer access right. This is because CreateNewChangeForAllNotInTarget wrongly attempts to create a new change for the base change, and hence does validation for the commit of the base change. The error message for the base change is: invalid committer ERROR: In commit 683c42e4ba60ffa68c820de9064b6c36238600c4 ERROR: committer email address other.user@example.com ERROR: does not match your user account. ERROR: ERROR: The following addresses are currently registered: ERROR: user@example.com ERROR: ERROR: To register an email address, please visit: ERROR: http://localhost:0/#/settings/contact This is confusing to the user who only uploaded a successor change but didn't touch the base change. Bug: Issue 5478 Change-Id: I04e25b5eb09e0c9540652c93eb1408d2fab39f6b Signed-off-by: Edwin Kempin <ekempin@google.com>
This commit is contained in:
@@ -1723,7 +1723,7 @@ public class ReceiveCommits {
|
||||
return;
|
||||
}
|
||||
|
||||
List<ChangeLookup> pending = new ArrayList<>();
|
||||
LinkedHashMap<RevCommit, ChangeLookup> pending = new LinkedHashMap<>();
|
||||
Set<Change.Key> newChangeIds = new HashSet<>();
|
||||
int maxBatchChanges = receiveConfig.getEffectiveMaxBatchChangesLimit(user);
|
||||
int total = 0;
|
||||
@@ -1757,7 +1757,8 @@ public class ReceiveCommits {
|
||||
mergedParents.remove(c);
|
||||
}
|
||||
|
||||
if (!existingRefs.isEmpty()) { // Commit is already tracked.
|
||||
boolean commitAlreadyTracked = !existingRefs.isEmpty();
|
||||
if (commitAlreadyTracked) {
|
||||
alreadyTracked++;
|
||||
// Corner cases where an existing commit might need a new group:
|
||||
// A) Existing commit has a null group; wasn't assigned during schema
|
||||
@@ -1778,6 +1779,39 @@ public class ReceiveCommits {
|
||||
if (!(newChangeForAllNotInTarget || magicBranch.base != null)) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
List<String> idList = c.getFooterLines(CHANGE_ID);
|
||||
|
||||
String idStr = !idList.isEmpty() ? idList.get(idList.size() - 1).trim() : null;
|
||||
|
||||
if (idStr != null) {
|
||||
pending.put(c, new ChangeLookup(c, new Change.Key(idStr)));
|
||||
} else {
|
||||
pending.put(c, new ChangeLookup(c));
|
||||
}
|
||||
int n = pending.size() + newChanges.size();
|
||||
if (maxBatchChanges != 0 && n > maxBatchChanges) {
|
||||
logDebug("{} changes exceeds limit of {}", n, maxBatchChanges);
|
||||
reject(
|
||||
magicBranch.cmd,
|
||||
"the number of pushed changes in a batch exceeds the max limit " + maxBatchChanges);
|
||||
newChanges = Collections.emptyList();
|
||||
return;
|
||||
}
|
||||
|
||||
if (commitAlreadyTracked) {
|
||||
boolean changeExistsOnDestBranch = false;
|
||||
for (ChangeData cd : pending.get(c).destChanges) {
|
||||
if (cd.change().getDest().equals(magicBranch.dest)) {
|
||||
changeExistsOnDestBranch = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (changeExistsOnDestBranch) {
|
||||
continue;
|
||||
}
|
||||
|
||||
logDebug("Creating new change for {} even though it is already tracked", name);
|
||||
}
|
||||
|
||||
@@ -1798,23 +1832,10 @@ public class ReceiveCommits {
|
||||
// TODO(dborowitz): Should we early return here?
|
||||
}
|
||||
|
||||
List<String> idList = c.getFooterLines(CHANGE_ID);
|
||||
if (idList.isEmpty()) {
|
||||
newChanges.add(new CreateRequest(c, magicBranch.dest.get()));
|
||||
continue;
|
||||
}
|
||||
|
||||
String idStr = idList.get(idList.size() - 1).trim();
|
||||
pending.add(new ChangeLookup(c, new Change.Key(idStr)));
|
||||
int n = pending.size() + newChanges.size();
|
||||
if (maxBatchChanges != 0 && n > maxBatchChanges) {
|
||||
logDebug("{} changes exceeds limit of {}", n, maxBatchChanges);
|
||||
reject(
|
||||
magicBranch.cmd,
|
||||
"the number of pushed changes in a batch exceeds the max limit " + maxBatchChanges);
|
||||
newChanges = Collections.emptyList();
|
||||
return;
|
||||
}
|
||||
}
|
||||
logDebug(
|
||||
"Finished initial RevWalk with {} commits total: {} already"
|
||||
@@ -1829,8 +1850,12 @@ public class ReceiveCommits {
|
||||
rejectImplicitMerges(mergedParents);
|
||||
}
|
||||
|
||||
for (Iterator<ChangeLookup> itr = pending.iterator(); itr.hasNext(); ) {
|
||||
for (Iterator<ChangeLookup> itr = pending.values().iterator(); itr.hasNext(); ) {
|
||||
ChangeLookup p = itr.next();
|
||||
if (p.changeKey == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (newChangeIds.contains(p.changeKey)) {
|
||||
logDebug("Multiple commits with Change-Id {}", p.changeKey);
|
||||
reject(magicBranch.cmd, SAME_CHANGE_ID_IN_MULTIPLE_CHANGES);
|
||||
@@ -2069,6 +2094,12 @@ public class ReceiveCommits {
|
||||
changeKey = key;
|
||||
destChanges = queryProvider.get().byBranchKey(magicBranch.dest, key);
|
||||
}
|
||||
|
||||
ChangeLookup(RevCommit c) throws OrmException {
|
||||
commit = c;
|
||||
destChanges = queryProvider.get().byBranchCommit(magicBranch.dest, c.getName());
|
||||
changeKey = null;
|
||||
}
|
||||
}
|
||||
|
||||
private class CreateRequest {
|
||||
|
||||
Reference in New Issue
Block a user