Allow to create a change for the initial commit of refs/meta/config
Normally you can only push commits for review to branches that exist. But there is an exception for the branch to which HEAD in the remote repository points (usually master). The same is true on submit, changes can only be submitted if the destination branch exists, except if the destination branch is the branch to which HEAD points. Relax this further and also allow to push an initial commit for review to the refs/meta/config branch and also allow to submit such a change. This is useful to setup an initial project configuration when the refs/meta/config branch is missing. Actually already today it is possible to create a change with an initial commit for the refs/meta/config branch, but then this change is not submittable because the destination branch is missing. The creation of such a change is possible by editing the access rights in the WebUI and then clicking on the 'Save for Review' button. This creates a change for the refs/meta/config branch regardless of whether the branch exists. Change-Id: I2e28fdd5384149d0ee32b10641652803c73842ab Signed-off-by: Edwin Kempin <ekempin@google.com>
This commit is contained in:
parent
9f3b888fcf
commit
f5a46a4109
@ -62,6 +62,7 @@ import com.google.gerrit.reviewdb.client.AccountGroup;
|
||||
import com.google.gerrit.reviewdb.client.Change;
|
||||
import com.google.gerrit.reviewdb.client.ChangeMessage;
|
||||
import com.google.gerrit.reviewdb.client.PatchSet;
|
||||
import com.google.gerrit.reviewdb.client.RefNames;
|
||||
import com.google.gerrit.server.ChangeMessagesUtil;
|
||||
import com.google.gerrit.server.git.ProjectConfig;
|
||||
import com.google.gerrit.server.git.receive.ReceiveConstants;
|
||||
@ -83,8 +84,11 @@ import java.util.regex.Pattern;
|
||||
import org.eclipse.jgit.api.errors.GitAPIException;
|
||||
import org.eclipse.jgit.junit.TestRepository;
|
||||
import org.eclipse.jgit.lib.ObjectId;
|
||||
import org.eclipse.jgit.lib.RefUpdate;
|
||||
import org.eclipse.jgit.lib.RefUpdate.Result;
|
||||
import org.eclipse.jgit.lib.Repository;
|
||||
import org.eclipse.jgit.revwalk.RevCommit;
|
||||
import org.eclipse.jgit.revwalk.RevWalk;
|
||||
import org.eclipse.jgit.transport.PushResult;
|
||||
import org.eclipse.jgit.transport.RefSpec;
|
||||
import org.eclipse.jgit.transport.RemoteRefUpdate;
|
||||
@ -182,6 +186,69 @@ public abstract class AbstractPushForReview extends AbstractDaemonTest {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void pushInitialCommitForRefsMetaConfigBranch() throws Exception {
|
||||
// delete refs/meta/config
|
||||
try (Repository repo = repoManager.openRepository(project);
|
||||
RevWalk rw = new RevWalk(repo)) {
|
||||
RefUpdate u = repo.updateRef(RefNames.REFS_CONFIG);
|
||||
u.setForceUpdate(true);
|
||||
u.setExpectedOldObjectId(repo.resolve(RefNames.REFS_CONFIG));
|
||||
assertThat(u.delete(rw)).isEqualTo(Result.FORCED);
|
||||
}
|
||||
|
||||
RevCommit c =
|
||||
testRepo
|
||||
.commit()
|
||||
.message("Initial commit")
|
||||
.author(admin.getIdent())
|
||||
.committer(admin.getIdent())
|
||||
.insertChangeId()
|
||||
.create();
|
||||
String id = GitUtil.getChangeId(testRepo, c).get();
|
||||
testRepo.reset(c);
|
||||
|
||||
String r = "refs/for/" + RefNames.REFS_CONFIG;
|
||||
PushResult pr = pushHead(testRepo, r, false);
|
||||
assertPushOk(pr, r);
|
||||
|
||||
ChangeInfo change = gApi.changes().id(id).info();
|
||||
assertThat(change.branch).isEqualTo(RefNames.REFS_CONFIG);
|
||||
assertThat(change.status).isEqualTo(ChangeStatus.NEW);
|
||||
|
||||
try (Repository repo = repoManager.openRepository(project)) {
|
||||
assertThat(repo.resolve(RefNames.REFS_CONFIG)).isNull();
|
||||
}
|
||||
|
||||
gApi.changes().id(change.id).current().review(ReviewInput.approve());
|
||||
gApi.changes().id(change.id).current().submit();
|
||||
|
||||
try (Repository repo = repoManager.openRepository(project)) {
|
||||
assertThat(repo.resolve(RefNames.REFS_CONFIG)).isEqualTo(c);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void pushInitialCommitForNormalNonExistingBranchFails() throws Exception {
|
||||
RevCommit c =
|
||||
testRepo
|
||||
.commit()
|
||||
.message("Initial commit")
|
||||
.author(admin.getIdent())
|
||||
.committer(admin.getIdent())
|
||||
.insertChangeId()
|
||||
.create();
|
||||
testRepo.reset(c);
|
||||
|
||||
String r = "refs/for/foo";
|
||||
PushResult pr = pushHead(testRepo, r, false);
|
||||
assertPushRejected(pr, r, "branch foo not found");
|
||||
|
||||
try (Repository repo = repoManager.openRepository(project)) {
|
||||
assertThat(repo.resolve("foo")).isNull();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void output() throws Exception {
|
||||
String url = canonicalWebUrl.get();
|
||||
|
@ -15,6 +15,7 @@
|
||||
package com.google.gerrit.server;
|
||||
|
||||
import com.google.gerrit.reviewdb.client.Branch;
|
||||
import com.google.gerrit.reviewdb.client.RefNames;
|
||||
import com.google.gerrit.server.git.GitRepositoryManager;
|
||||
import java.io.IOException;
|
||||
import org.eclipse.jgit.errors.RepositoryNotFoundException;
|
||||
@ -37,7 +38,8 @@ public class ProjectUtil {
|
||||
try (Repository repo = repoManager.openRepository(branch.getParentKey())) {
|
||||
boolean exists = repo.getRefDatabase().exactRef(branch.get()) != null;
|
||||
if (!exists) {
|
||||
exists = repo.getFullBranch().equals(branch.get());
|
||||
exists =
|
||||
repo.getFullBranch().equals(branch.get()) || RefNames.REFS_CONFIG.equals(branch.get());
|
||||
}
|
||||
return exists;
|
||||
}
|
||||
|
@ -19,6 +19,7 @@ import static com.google.common.base.Preconditions.checkState;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.google.gerrit.reviewdb.client.Branch;
|
||||
import com.google.gerrit.reviewdb.client.Project;
|
||||
import com.google.gerrit.reviewdb.client.RefNames;
|
||||
import com.google.gerrit.reviewdb.server.ReviewDb;
|
||||
import com.google.gerrit.server.IdentifiedUser;
|
||||
import com.google.gerrit.server.git.CodeReviewCommit.CodeReviewRevWalk;
|
||||
@ -135,7 +136,8 @@ public class MergeOpRepoManager implements AutoCloseable {
|
||||
update = or.repo.updateRef(name.get());
|
||||
if (update.getOldObjectId() != null) {
|
||||
oldTip = or.rw.parseCommit(update.getOldObjectId());
|
||||
} else if (Objects.equals(or.repo.getFullBranch(), name.get())) {
|
||||
} else if (Objects.equals(or.repo.getFullBranch(), name.get())
|
||||
|| Objects.equals(RefNames.REFS_CONFIG, name.get())) {
|
||||
oldTip = null;
|
||||
update.setExpectedOldObjectId(ObjectId.zeroId());
|
||||
} else {
|
||||
|
@ -1430,7 +1430,9 @@ class ReceiveCommits {
|
||||
logDebug("Handling {}", RefNames.REFS_USERS_SELF);
|
||||
ref = RefNames.refsUsers(user.getAccountId());
|
||||
}
|
||||
if (!rp.getAdvertisedRefs().containsKey(ref) && !ref.equals(readHEAD(repo))) {
|
||||
if (!rp.getAdvertisedRefs().containsKey(ref)
|
||||
&& !ref.equals(readHEAD(repo))
|
||||
&& !ref.equals(RefNames.REFS_CONFIG)) {
|
||||
logDebug("Ref {} not found", ref);
|
||||
if (ref.startsWith(Constants.R_HEADS)) {
|
||||
String n = ref.substring(Constants.R_HEADS.length());
|
||||
|
Loading…
Reference in New Issue
Block a user