Fix force push

Since change I3dbf66f17, the force push was no longer working. The intent
was to set allowNonFastForwards to true for changeEdit but it was always
setting it to false when not a changeEdit.

Change-Id: Ic4ead13ef5f2fabf2ea2e487c0de0f9ecb1ef52f
This commit is contained in:
Hugo Arès
2015-03-02 12:07:21 -05:00
committed by David Pursehouse
parent 7c3402f44d
commit 99f9f99efd
5 changed files with 95 additions and 3 deletions

View File

@@ -327,13 +327,21 @@ public abstract class AbstractDaemonTest {
protected void grant(String permission, Project.NameKey project, String ref)
throws RepositoryNotFoundException, IOException, ConfigInvalidException {
grant(permission, project, ref, false);
}
protected void grant(String permission, Project.NameKey project, String ref,
boolean force) throws RepositoryNotFoundException, IOException,
ConfigInvalidException {
MetaDataUpdate md = metaDataUpdateFactory.create(project);
md.setMessage(String.format("Grant %s on %s", permission, ref));
ProjectConfig config = ProjectConfig.read(md);
AccessSection s = config.getAccessSection(ref, true);
Permission p = s.getPermission(permission, true);
AccountGroup adminGroup = groupCache.get(new AccountGroup.NameKey("Administrators"));
p.add(new PermissionRule(config.resolve(adminGroup)));
PermissionRule rule = new PermissionRule(config.resolve(adminGroup));
rule.setForce(force);
p.add(rule);
config.commit(md);
projectCache.evict(config.getProject());
}

View File

@@ -193,7 +193,13 @@ public class GitUtil {
public static PushResult pushHead(Git git, String ref, boolean pushTags)
throws GitAPIException {
return pushHead(git, ref, pushTags, false);
}
public static PushResult pushHead(Git git, String ref, boolean pushTags,
boolean force) throws GitAPIException {
PushCommand pushCmd = git.push();
pushCmd.setForce(force);
pushCmd.setRefSpecs(new RefSpec("HEAD:" + ref));
if (pushTags) {
pushCmd.setPushTags();

View File

@@ -113,6 +113,7 @@ public class PushOneCommit {
private final String content;
private String changeId;
private Tag tag;
private boolean force;
@AssistedInject
PushOneCommit(ChangeNotes.Factory notesFactory,
@@ -189,13 +190,17 @@ public class PushOneCommit {
}
tagCommand.call();
}
return new Result(ref, pushHead(git, ref, tag != null), c, subject);
return new Result(ref, pushHead(git, ref, tag != null, force), c, subject);
}
public void setTag(final Tag tag) {
this.tag = tag;
}
public void setForce(boolean force) {
this.force = force;
}
public class Result {
private final String ref;
private final PushResult result;

View File

@@ -0,0 +1,70 @@
// Copyright (C) 2015 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package com.google.gerrit.acceptance.git;
import static com.google.common.truth.Truth.assertThat;
import static org.eclipse.jgit.lib.Constants.HEAD;
import com.google.gerrit.acceptance.AbstractDaemonTest;
import com.google.gerrit.acceptance.PushOneCommit;
import com.google.gerrit.common.data.Permission;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.RefUpdate;
import org.junit.Test;
public class ForcePushIT extends AbstractDaemonTest {
@Test
public void forcePushNotAllowed() throws Exception {
ObjectId initial = git.getRepository().getRef(HEAD).getLeaf().getObjectId();
PushOneCommit push1 =
pushFactory.create(db, admin.getIdent(), "change1", "a.txt", "content");
PushOneCommit.Result r1 = push1.to(git, "refs/heads/master");
r1.assertOkStatus();
// Reset HEAD to initial so the new change is a non-fast forward
RefUpdate ru = git.getRepository().updateRef(HEAD);
ru.setNewObjectId(initial);
assertThat(ru.forceUpdate()).isEqualTo(RefUpdate.Result.FORCED);
PushOneCommit push2 =
pushFactory.create(db, admin.getIdent(), "change2", "b.txt", "content");
push2.setForce(true);
PushOneCommit.Result r2 = push2.to(git, "refs/heads/master");
r2.assertErrorStatus("non-fast forward");
}
@Test
public void forcePushAllowed() throws Exception {
ObjectId initial = git.getRepository().getRef(HEAD).getLeaf().getObjectId();
grant(Permission.PUSH, project, "refs/*", true);
PushOneCommit push1 =
pushFactory.create(db, admin.getIdent(), "change1", "a.txt", "content");
PushOneCommit.Result r1 = push1.to(git, "refs/heads/master");
r1.assertOkStatus();
// Reset HEAD to initial so the new change is a non-fast forward
RefUpdate ru = git.getRepository().updateRef(HEAD);
ru.setNewObjectId(initial);
assertThat(ru.forceUpdate()).isEqualTo(RefUpdate.Result.FORCED);
PushOneCommit push2 =
pushFactory.create(db, admin.getIdent(), "change2", "b.txt", "content");
push2.setForce(true);
PushOneCommit.Result r2 = push2.to(git, "refs/heads/master");
r2.assertOkStatus();
}
}

View File

@@ -567,7 +567,10 @@ public class ReceiveCommits {
if (!batch.getCommands().isEmpty()) {
try {
batch.setAllowNonFastForwards(magicBranch != null && magicBranch.edit);
if (!batch.isAllowNonFastForwards() && magicBranch != null
&& magicBranch.edit) {
batch.setAllowNonFastForwards(true);
}
batch.execute(rp.getRevWalk(), commandProgress);
} catch (IOException err) {
int cnt = 0;