Merge "Allow opening new changes on existing commits"

This commit is contained in:
Saša Živkov
2013-04-24 13:32:38 +00:00
committed by Gerrit Code Review
2 changed files with 45 additions and 5 deletions

View File

@@ -353,6 +353,20 @@ If the merge fails the change stays open, but when pushing a new patch
set the merge can be reattempted by using `%submit` again. set the merge can be reattempted by using `%submit` again.
[[base]]
Selecting Merge Base
~~~~~~~~~~~~~~~~~~~~
By default new changes are opened only for new unique commits
that have never before been seen by the Gerrit server. Clients
may override that behavior and force new changes to be created
by setting the merge base SHA-1 using the '%base' argument:
====
git push ssh://john.doe@git.example.com:29418/kernel/common HEAD:refs/for/master%base=$(git rev-parse origin/master)
====
repo upload repo upload
----------- -----------

View File

@@ -1004,6 +1004,10 @@ public class ReceiveCommits {
RefControl ctl; RefControl ctl;
Set<Account.Id> reviewer = Sets.newLinkedHashSet(); Set<Account.Id> reviewer = Sets.newLinkedHashSet();
Set<Account.Id> cc = 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") @Option(name = "--topic", metaVar = "NAME", usage = "attach topic to changes")
String topic; String topic;
@@ -1148,13 +1152,31 @@ public class ReceiveCommits {
reject(cmd, "submit not allowed"); 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 // Validate that the new commits are connected with the target
// branch. If they aren't, we want to abort. We do this check by // 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 // looking to see if we can compute a merge base between the new
// commits and the target branch head. // commits and the target branch head.
// //
try { try {
final RevWalk walk = rp.getRevWalk();
final RevCommit tip = walk.parseCommit(magicBranch.cmd.getNewId()); final RevCommit tip = walk.parseCommit(magicBranch.cmd.getNewId());
Ref targetRef = rp.getAdvertisedRefs().get(magicBranch.ctl.getRefName()); Ref targetRef = rp.getAdvertisedRefs().get(magicBranch.ctl.getRefName());
if (targetRef == null || targetRef.getObjectId() == null) { if (targetRef == null || targetRef.getObjectId() == null) {
@@ -1284,10 +1306,14 @@ public class ReceiveCommits {
try { try {
Set<ObjectId> existing = Sets.newHashSet(); Set<ObjectId> existing = Sets.newHashSet();
walk.markStart(walk.parseCommit(magicBranch.cmd.getNewId())); walk.markStart(walk.parseCommit(magicBranch.cmd.getNewId()));
if (magicBranch.baseCommit != null) {
walk.markUninteresting(magicBranch.baseCommit);
} else {
markHeadsAsUninteresting( markHeadsAsUninteresting(
walk, walk,
existing, existing,
magicBranch.ctl != null ? magicBranch.ctl.getRefName() : null); magicBranch.ctl != null ? magicBranch.ctl.getRefName() : null);
}
List<ChangeLookup> pending = Lists.newArrayList(); List<ChangeLookup> pending = Lists.newArrayList();
final Set<Change.Key> newChangeIds = new HashSet<Change.Key>(); final Set<Change.Key> newChangeIds = new HashSet<Change.Key>();