Allow opening new changes on existing commits

The %base argument can be used with refs/for/ to identify a specific
revision the server should start to look for new commits at. Any
commits in the range $base..$tip will be opened as a new change,
even if the commit already has another change on a different branch.

Change-Id: Ic2ea9b7c53df3b99d29043cd6a6fd68214f3398f
This commit is contained in:
Shawn Pearce
2013-04-22 11:50:23 -07:00
parent c36a0e01d2
commit 5d8a290d06
2 changed files with 45 additions and 5 deletions

View File

@@ -1003,6 +1003,10 @@ public class ReceiveCommits {
RefControl ctl;
Set<Account.Id> reviewer = Sets.newLinkedHashSet();
Set<Account.Id> cc = Sets.newLinkedHashSet();
RevCommit baseCommit;
@Option(name = "--base", metaVar = "BASE", usage = "merge base of changes")
ObjectId base;
@Option(name = "--topic", metaVar = "NAME", usage = "attach topic to changes")
String topic;
@@ -1147,13 +1151,31 @@ public class ReceiveCommits {
reject(cmd, "submit not allowed");
}
RevWalk walk = rp.getRevWalk();
if (magicBranch.base != null) {
try {
magicBranch.baseCommit = walk.parseCommit(magicBranch.base);
} catch (IncorrectObjectTypeException notCommit) {
reject(cmd, "base must be a commit");
return;
} catch (MissingObjectException e) {
reject(cmd, "base not found");
return;
} catch (IOException e) {
log.warn(String.format(
"Project %s cannot read %s",
project.getName(), magicBranch.base.name()), e);
reject(cmd, "internal server error");
return;
}
}
// Validate that the new commits are connected with the target
// branch. If they aren't, we want to abort. We do this check by
// looking to see if we can compute a merge base between the new
// commits and the target branch head.
//
try {
final RevWalk walk = rp.getRevWalk();
final RevCommit tip = walk.parseCommit(magicBranch.cmd.getNewId());
Ref targetRef = rp.getAdvertisedRefs().get(magicBranch.ctl.getRefName());
if (targetRef == null || targetRef.getObjectId() == null) {
@@ -1283,10 +1305,14 @@ public class ReceiveCommits {
try {
Set<ObjectId> existing = Sets.newHashSet();
walk.markStart(walk.parseCommit(magicBranch.cmd.getNewId()));
markHeadsAsUninteresting(
walk,
existing,
magicBranch.ctl != null ? magicBranch.ctl.getRefName() : null);
if (magicBranch.baseCommit != null) {
walk.markUninteresting(magicBranch.baseCommit);
} else {
markHeadsAsUninteresting(
walk,
existing,
magicBranch.ctl != null ? magicBranch.ctl.getRefName() : null);
}
List<ChangeLookup> pending = Lists.newArrayList();
final Set<Change.Key> newChangeIds = new HashSet<Change.Key>();