Merge branch 'stable-2.11'

* stable-2.11:
  Show correct change status for draft patch sets
  Add an acceptance test for pushing changes with Signed-off-by
  Fix client error when current patch set is not visible to user
  ReceiveCommits: Include canonical URL in "change closed" error
  ListDashboards: Use correct channel for logger
  Call NewProjectCreatedListeners after project creation is complete
  PushOneCommit: Fix usage of assertThat

Change-Id: I6cda7b102dae54894f8c88b395aa48572c823d86
This commit is contained in:
David Pursehouse
2015-08-05 17:12:43 +09:00
9 changed files with 70 additions and 22 deletions

View File

@@ -500,6 +500,15 @@ public abstract class AbstractDaemonTest {
projectCache.evict(config.getProject());
}
protected void setUseSignedOffBy(InheritableBoolean value)
throws Exception {
MetaDataUpdate md = metaDataUpdateFactory.create(project);
ProjectConfig config = ProjectConfig.read(md);
config.getProject().setUseSignedOffBy(value);
config.commit(md);
projectCache.evict(config.getProject());
}
protected void deny(String permission, AccountGroup.UUID id, String ref)
throws Exception {
ProjectConfig cfg = projectCache.checkedGet(project).getConfig();
@@ -545,6 +554,13 @@ public abstract class AbstractDaemonTest {
saveProjectConfig(project, cfg);
}
protected void blockForgeCommitter(Project.NameKey project, String ref)
throws Exception {
ProjectConfig cfg = projectCache.checkedGet(project).getConfig();
block(cfg, Permission.FORGE_COMMITTER, REGISTERED_USERS, ref);
saveProjectConfig(project, cfg);
}
protected PushOneCommit.Result pushTo(String ref) throws Exception {
PushOneCommit push = pushFactory.create(db, admin.getIdent(), testRepo);
return push.to(ref);

View File

@@ -22,6 +22,7 @@ import com.google.gerrit.acceptance.AbstractDaemonTest;
import com.google.gerrit.acceptance.GitUtil;
import com.google.gerrit.acceptance.PushOneCommit;
import com.google.gerrit.acceptance.TestAccount;
import com.google.gerrit.extensions.client.InheritableBoolean;
import com.google.gerrit.extensions.common.ChangeInfo;
import com.google.gerrit.extensions.common.EditInfo;
import com.google.gerrit.extensions.common.LabelInfo;
@@ -285,4 +286,29 @@ public abstract class AbstractPushForReview extends AbstractDaemonTest {
PushOneCommit.Result r = pushTo("refs/for/master%hashtag=tag1");
r.assertErrorStatus("cannot add hashtags; noteDb is disabled");
}
@Test
public void testPushCommitUsingSignedOffBy() throws Exception {
PushOneCommit push =
pushFactory.create(db, admin.getIdent(), testRepo, PushOneCommit.SUBJECT,
"b.txt", "anotherContent");
PushOneCommit.Result r = push.to("refs/for/master");
r.assertOkStatus();
setUseSignedOffBy(InheritableBoolean.TRUE);
blockForgeCommitter(project, "refs/heads/master");
push = pushFactory.create(db, admin.getIdent(), testRepo,
PushOneCommit.SUBJECT + String.format(
"\n\nSigned-off-by: %s <%s>", admin.fullName, admin.email),
"b.txt", "anotherContent");
r = push.to("refs/for/master");
r.assertOkStatus();
push = pushFactory.create(db, admin.getIdent(), testRepo,
PushOneCommit.SUBJECT, "b.txt", "anotherContent");
r = push.to("refs/for/master");
r.assertErrorStatus(
"not Signed-off-by author/committer/uploader in commit message footer");
}
}

View File

@@ -1112,7 +1112,10 @@ public class ChangeScreen extends Screen {
}
private boolean isSubmittable(ChangeInfo info) {
boolean canSubmit = info.status().isOpen();
boolean canSubmit =
info.status().isOpen() &&
revision.equals(info.currentRevision()) &&
!info.revision(revision).draft();
if (canSubmit && info.status() == Change.Status.NEW) {
for (String name : info.labels()) {
LabelInfo label = info.label(name);
@@ -1200,7 +1203,8 @@ public class ChangeScreen extends Screen {
statusText.setInnerText(Util.C.notCurrent());
labels.setVisible(false);
} else {
statusText.setInnerText(Util.toLongString(info.status()));
Status s = info.revision(revision).draft() ? Status.DRAFT : info.status();
statusText.setInnerText(Util.toLongString(s));
}
if (Gerrit.isSignedIn()) {

View File

@@ -150,12 +150,12 @@ class DiffTable extends Composite {
}
void set(DiffPreferences prefs, JsArray<RevisionInfo> list, DiffInfo info,
boolean editExists, int currentPatchSet, boolean open, boolean binary) {
boolean editExists, boolean current, boolean open, boolean binary) {
this.changeType = info.changeType();
patchSetSelectBoxA.setUpPatchSetNav(list, info.metaA(), editExists,
currentPatchSet, open, binary);
current, open, binary);
patchSetSelectBoxB.setUpPatchSetNav(list, info.metaB(), editExists,
currentPatchSet, open, binary);
current, open, binary);
JsArrayString hdr = info.diffHeader();
if (hdr != null) {

View File

@@ -82,7 +82,7 @@ class PatchSetSelectBox extends Composite {
}
void setUpPatchSetNav(JsArray<RevisionInfo> list, DiffInfo.FileMeta meta,
boolean editExists, int currentPatchSet, boolean open, boolean binary) {
boolean editExists, boolean current, boolean open, boolean binary) {
InlineHyperlink baseLink = null;
InlineHyperlink selectedLink = null;
if (sideA) {
@@ -112,7 +112,7 @@ class PatchSetSelectBox extends Composite {
}
if (!binary && open && idActive != null && Gerrit.isSignedIn()) {
if ((editExists && idActive.get() == 0)
|| (!editExists && idActive.get() == currentPatchSet)) {
|| (!editExists && current)) {
linkPanel.add(createEditIcon());
}
}

View File

@@ -243,10 +243,12 @@ public class SideBySide extends Screen {
info.setEdit(edit);
info.revisions().put(edit.name(), RevisionInfo.fromEdit(edit));
}
int currentPatchSet = info.revision(info.currentRevision())._number();
String currentRevision = info.currentRevision();
boolean current = currentRevision != null &&
revision.get() == info.revision(currentRevision)._number();
JsArray<RevisionInfo> list = info.revisions().values();
RevisionInfo.sortRevisionInfoByNumber(list);
diffTable.set(prefs, list, diff, edit != null, currentPatchSet,
diffTable.set(prefs, list, diff, edit != null, current,
changeStatus.isOpen(), diff.binary());
header.setChangeInfo(info);
}

View File

@@ -1474,7 +1474,7 @@ public class ReceiveCommits {
final boolean checkMergedInto, final Change change,
final RevCommit newCommit) {
if (change.getStatus().isClosed()) {
reject(cmd, "change " + change.getId() + " closed");
reject(cmd, "change " + canonicalWebUrl + change.getId() + " closed");
return false;
}

View File

@@ -237,6 +237,17 @@ public class CreateProject implements RestModifyView<TopLevelResource, ProjectIn
// It does not exist, safe to ignore.
}
try (Repository repo = repoManager.createRepository(nameKey)) {
RefUpdate u = repo.updateRef(Constants.HEAD);
u.disableRefLog();
u.link(head);
createProjectConfig(args);
if (!args.permissionsOnly
&& args.createEmptyCommit) {
createEmptyCommits(repo, nameKey, args.branch);
}
NewProjectCreatedListener.Event event = new NewProjectCreatedListener.Event() {
@Override
public String getProjectName() {
@@ -256,17 +267,6 @@ public class CreateProject implements RestModifyView<TopLevelResource, ProjectIn
}
}
RefUpdate u = repo.updateRef(Constants.HEAD);
u.disableRefLog();
u.link(head);
createProjectConfig(args);
if (!args.permissionsOnly
&& args.createEmptyCommit) {
createEmptyCommits(repo, nameKey, args.branch);
}
return projectCache.get(nameKey).getProject();
}
} catch (RepositoryCaseMismatchException e) {

View File

@@ -40,7 +40,7 @@ import java.io.IOException;
import java.util.List;
class ListDashboards implements RestReadView<ProjectResource> {
private static final Logger log = LoggerFactory.getLogger(DashboardsCollection.class);
private static final Logger log = LoggerFactory.getLogger(ListDashboards.class);
private final GitRepositoryManager gitManager;