Require branches to always start from commits
When creating a new branch, require that the branch points to a commit object, and not to another type such as tag, tree, or blob. Bug: issue 575 Change-Id: Ia0ebd25eb8d67fc113dee5a74fd51454f4bf180f Signed-off-by: Shawn O. Pearce <sop@google.com>
This commit is contained in:
parent
7187981def
commit
5710504c4e
|
@ -107,7 +107,19 @@ class AddBranch extends Handler<ListBranchesResult> {
|
|||
try {
|
||||
final ObjectId revid = parseStartingRevision(repo);
|
||||
final RevWalk rw = verifyConnected(repo, revid);
|
||||
final RevObject object = rw.parseAny(revid);
|
||||
RevObject object = rw.parseAny(revid);
|
||||
|
||||
if (refname.startsWith(Constants.R_HEADS)) {
|
||||
// Ensure that what we start the branch from is a commit. If we
|
||||
// were given a tag, deference to the commit instead.
|
||||
//
|
||||
try {
|
||||
object = rw.parseCommit(object);
|
||||
} catch (IncorrectObjectTypeException notCommit) {
|
||||
throw new IllegalStateException(startingRevision + " not a commit");
|
||||
}
|
||||
}
|
||||
|
||||
if (!refControl.canCreate(rw, object)) {
|
||||
throw new IllegalStateException("Cannot create " + refname);
|
||||
}
|
||||
|
@ -115,7 +127,7 @@ class AddBranch extends Handler<ListBranchesResult> {
|
|||
try {
|
||||
final RefUpdate u = repo.updateRef(refname);
|
||||
u.setExpectedOldObjectId(ObjectId.zeroId());
|
||||
u.setNewObjectId(revid);
|
||||
u.setNewObjectId(object.copy());
|
||||
u.setRefLogIdent(identifiedUser.newRefLogIdent());
|
||||
u.setRefLogMessage("created via web from " + startingRevision, false);
|
||||
final RefUpdate.Result result = u.update(rw);
|
||||
|
|
|
@ -36,13 +36,11 @@ import com.google.gerrit.reviewdb.PatchSetInfo;
|
|||
import com.google.gerrit.reviewdb.Project;
|
||||
import com.google.gerrit.reviewdb.RevId;
|
||||
import com.google.gerrit.reviewdb.ReviewDb;
|
||||
import com.google.gerrit.reviewdb.TrackingId;
|
||||
import com.google.gerrit.server.ChangeUtil;
|
||||
import com.google.gerrit.server.GerritPersonIdent;
|
||||
import com.google.gerrit.server.IdentifiedUser;
|
||||
import com.google.gerrit.server.account.AccountResolver;
|
||||
import com.google.gerrit.server.config.CanonicalWebUrl;
|
||||
import com.google.gerrit.server.config.TrackingFooter;
|
||||
import com.google.gerrit.server.config.TrackingFooters;
|
||||
import com.google.gerrit.server.mail.CreateChangeSender;
|
||||
import com.google.gerrit.server.mail.EmailException;
|
||||
|
@ -57,6 +55,7 @@ import com.google.gwtorm.client.OrmException;
|
|||
import com.google.inject.Inject;
|
||||
import com.google.inject.assistedinject.Assisted;
|
||||
|
||||
import org.eclipse.jgit.errors.IncorrectObjectTypeException;
|
||||
import org.eclipse.jgit.errors.MissingObjectException;
|
||||
import org.eclipse.jgit.lib.Constants;
|
||||
import org.eclipse.jgit.lib.ObjectId;
|
||||
|
@ -471,7 +470,7 @@ public class ReceiveCommits implements PreReceiveHook, PostReceiveHook {
|
|||
}
|
||||
|
||||
private void parseCreate(final ReceiveCommand cmd) {
|
||||
final RevObject obj;
|
||||
RevObject obj;
|
||||
try {
|
||||
obj = rp.getRevWalk().parseAny(cmd.getNewId());
|
||||
} catch (IOException err) {
|
||||
|
@ -481,6 +480,10 @@ public class ReceiveCommits implements PreReceiveHook, PostReceiveHook {
|
|||
return;
|
||||
}
|
||||
|
||||
if (isHead(cmd) && !isCommit(cmd)) {
|
||||
return;
|
||||
}
|
||||
|
||||
RefControl ctl = projectControl.controlForRef(cmd.getRefName());
|
||||
if (ctl.canCreate(rp.getRevWalk(), obj)) {
|
||||
validateNewCommits(ctl, cmd);
|
||||
|
@ -493,6 +496,10 @@ public class ReceiveCommits implements PreReceiveHook, PostReceiveHook {
|
|||
private void parseUpdate(final ReceiveCommand cmd) {
|
||||
RefControl ctl = projectControl.controlForRef(cmd.getRefName());
|
||||
if (ctl.canUpdate()) {
|
||||
if (isHead(cmd) && !isCommit(cmd)) {
|
||||
return;
|
||||
}
|
||||
|
||||
validateNewCommits(ctl, cmd);
|
||||
// Let the core receive process handle it
|
||||
} else {
|
||||
|
@ -500,6 +507,25 @@ public class ReceiveCommits implements PreReceiveHook, PostReceiveHook {
|
|||
}
|
||||
}
|
||||
|
||||
private boolean isCommit(final ReceiveCommand cmd) {
|
||||
RevObject obj;
|
||||
try {
|
||||
obj = rp.getRevWalk().parseAny(cmd.getNewId());
|
||||
} catch (IOException err) {
|
||||
log.error("Invalid object " + cmd.getNewId().name() + " for "
|
||||
+ cmd.getRefName(), err);
|
||||
reject(cmd, "invalid object");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (obj instanceof RevCommit) {
|
||||
return true;
|
||||
} else {
|
||||
reject(cmd, "not a commit");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private void parseDelete(final ReceiveCommand cmd) {
|
||||
RefControl ctl = projectControl.controlForRef(cmd.getRefName());
|
||||
if (ctl.canDelete()) {
|
||||
|
|
Loading…
Reference in New Issue