Merge "Tokenized REST API POST handler"
diff --git a/Documentation/licenses.txt b/Documentation/licenses.txt
index 4186026..7787fe8 100644
--- a/Documentation/licenses.txt
+++ b/Documentation/licenses.txt
@@ -28,7 +28,7 @@
|Apache Commons Pool | <<apache2,Apache License 2.0>>
|Apache Log4J | <<apache2,Apache License 2.0>>
|Apache MINA | <<apache2,Apache License 2.0>>
-|Apache Tomact Servlet API | <<apache2,Apache License 2.0>>
+|Apache Tomcat Servlet API | <<apache2,Apache License 2.0>>
|Apache SSHD | <<apache2,Apache License 2.0>>, see also <<sshd,NOTICE>>
|Apache Velocity | <<apache2,Apache License 2.0>>
|Apache Xerces | <<apache2,Apache License 2.0>>
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/Gerrit.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/Gerrit.java
index 1b23804..be74428 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/Gerrit.java
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/Gerrit.java
@@ -15,6 +15,7 @@
package com.google.gerrit.client;
import static com.google.gerrit.common.data.GlobalCapability.ADMINISTRATE_SERVER;
+import static com.google.gerrit.common.data.GlobalCapability.CREATE_PROJECT;
import com.google.gerrit.client.account.AccountCapabilities;
import com.google.gerrit.client.auth.openid.OpenIdSignInDialog;
@@ -584,10 +585,23 @@
addDiffLink(diffBar, C.menuDiffPatchSets(), PatchScreen.TopView.PATCH_SETS);
addDiffLink(diffBar, C.menuDiffFiles(), PatchScreen.TopView.FILES);
+ final LinkMenuBar projectsBar = new LinkMenuBar();
+ addLink(projectsBar, C.menuProjectsList(), PageLinks.ADMIN_PROJECTS);
+ if(signedIn) {
+ AccountCapabilities.all(new GerritCallback<AccountCapabilities>() {
+ @Override
+ public void onSuccess(AccountCapabilities result) {
+ if (result.canPerform(CREATE_PROJECT)) {
+ addLink(projectsBar, C.menuProjectsCreate(), PageLinks.ADMIN_CREATE_PROJECT);
+ }
+ }
+ }, CREATE_PROJECT);
+ }
+ menuLeft.add(projectsBar, C.menuProjects());
+
if (signedIn) {
final LinkMenuBar menuBar = new LinkMenuBar();
addLink(menuBar, C.menuGroups(), PageLinks.ADMIN_GROUPS);
- addLink(menuBar, C.menuProjects(), PageLinks.ADMIN_PROJECTS);
AccountCapabilities.all(new GerritCallback<AccountCapabilities>() {
@Override
public void onSuccess(AccountCapabilities result) {
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/GerritConstants.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/GerritConstants.java
index 09e6b84..c47c789 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/GerritConstants.java
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/GerritConstants.java
@@ -68,10 +68,13 @@
String menuDiffPatchSets();
String menuDiffFiles();
+ String menuProjects();
+ String menuProjectsList();
+ String menuProjectsCreate();
+
String menuAdmin();
String menuPeople();
String menuGroups();
- String menuProjects();
String menuPlugins();
String menuDocumentation();
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/GerritConstants.properties b/gerrit-gwtui/src/main/java/com/google/gerrit/client/GerritConstants.properties
index 294ba49..67ebe2a 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/GerritConstants.properties
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/GerritConstants.properties
@@ -51,10 +51,13 @@
menuDiffPatchSets = Patch Sets
menuDiffFiles = Files
+menuProjects = Projects
+menuProjectsList = List
+menuProjectsCreate = Create New Project
+
menuAdmin = Admin
menuPeople = People
menuGroups = Groups
-menuProjects = Projects
menuPlugins = Plugins
menuDocumentation = Documentation
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/GerritCss.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/GerritCss.java
index cb40d69..9cbf5cd 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/GerritCss.java
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/GerritCss.java
@@ -79,7 +79,6 @@
String contributorAgreementShortDescription();
String coverMessage();
String createGroupLink();
- String createProjectLink();
String createProjectPanel();
String dataCell();
String dataHeader();
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/GerritResources.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/GerritResources.java
index b5c0900..d763ff1 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/GerritResources.java
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/GerritResources.java
@@ -39,4 +39,7 @@
@Source("redNot.png")
public ImageResource redNot();
+
+ @Source("downloadIcon.png")
+ public ImageResource downloadIcon();
}
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/admin/AdminConstants.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/admin/AdminConstants.java
index 2d49f5d..a085ce5 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/admin/AdminConstants.java
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/admin/AdminConstants.java
@@ -60,7 +60,6 @@
String noMembersInfo();
String headingExternalGroup();
String headingCreateGroup();
- String headingCreateProject();
String headingParentProjectName();
String columnProjectName();
String headingAgreements();
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/admin/AdminConstants.properties b/gerrit-gwtui/src/main/java/com/google/gerrit/client/admin/AdminConstants.properties
index 17fba14..406f3d3 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/admin/AdminConstants.properties
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/admin/AdminConstants.properties
@@ -41,7 +41,6 @@
noMembersInfo = Group Members can only be viewed for Gerrit internal groups. For external groups and Gerrit system groups the members cannot be displayed.
headingExternalGroup = Selected External Group
headingCreateGroup = Create New Group
-headingCreateProject = Create New Project
headingAgreements = Contributor Agreements
projectSubmitType_FAST_FORWARD_ONLY = Fast Forward Only
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/admin/ProjectListScreen.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/admin/ProjectListScreen.java
index 5cb178c..d911c93 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/admin/ProjectListScreen.java
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/admin/ProjectListScreen.java
@@ -14,12 +14,7 @@
package com.google.gerrit.client.admin;
-import static com.google.gerrit.common.data.GlobalCapability.CREATE_PROJECT;
-
import com.google.gerrit.client.Dispatcher;
-import com.google.gerrit.client.Gerrit;
-import com.google.gerrit.client.account.AccountCapabilities;
-import com.google.gerrit.client.rpc.GerritCallback;
import com.google.gerrit.client.projects.ProjectInfo;
import com.google.gerrit.client.projects.ProjectMap;
import com.google.gerrit.client.rpc.ScreenLoadCallback;
@@ -28,22 +23,13 @@
import com.google.gerrit.client.ui.Screen;
import com.google.gerrit.common.PageLinks;
import com.google.gwt.user.client.History;
-import com.google.gwt.user.client.ui.VerticalPanel;
public class ProjectListScreen extends Screen {
- private VerticalPanel createProjectLinkPanel;
private ProjectsTable projects;
@Override
protected void onLoad() {
super.onLoad();
- createProjectLinkPanel.setVisible(false);
- AccountCapabilities.all(new GerritCallback<AccountCapabilities>() {
- @Override
- public void onSuccess(AccountCapabilities ac) {
- createProjectLinkPanel.setVisible(ac.canPerform(CREATE_PROJECT));
- }
- }, CREATE_PROJECT);
ProjectMap.all(new ScreenLoadCallback<ProjectMap>(this) {
@Override
protected void preDisplay(final ProjectMap result) {
@@ -58,13 +44,6 @@
super.onInitUI();
setPageTitle(Util.C.projectListTitle());
- createProjectLinkPanel = new VerticalPanel();
- createProjectLinkPanel.setStyleName(Gerrit.RESOURCES.css()
- .createProjectLink());
- createProjectLinkPanel.add(new Hyperlink(Util.C.headingCreateProject(),
- PageLinks.ADMIN_CREATE_PROJECT));
- add(createProjectLinkPanel);
-
projects = new ProjectsTable() {
@Override
protected void onOpenRow(final int row) {
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/changes/ChangeTable.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/changes/ChangeTable.java
index 97bb4ca..3a13297 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/changes/ChangeTable.java
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/changes/ChangeTable.java
@@ -209,6 +209,8 @@
if (! c.isLatest()) {
s += " [OUTDATED]";
table.getRowFormatter().addStyleName(row, Gerrit.RESOURCES.css().outdated());
+ } else if (Change.Status.ABANDONED.equals(c.getStatus())) {
+ table.getRowFormatter().addStyleName(row, Gerrit.RESOURCES.css().outdated());
} else {
table.getRowFormatter().removeStyleName(row, Gerrit.RESOURCES.css().outdated());
}
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/changes/PatchSetsBlock.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/changes/PatchSetsBlock.java
index 005423f..b9ed4e7 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/changes/PatchSetsBlock.java
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/changes/PatchSetsBlock.java
@@ -89,6 +89,12 @@
for (final PatchSet ps : patchSets) {
final PatchSetComplexDisclosurePanel p =
new PatchSetComplexDisclosurePanel(ps, ps == currps);
+ if (diffBaseId != null) {
+ p.setDiffBaseId(diffBaseId);
+ if (ps == currps) {
+ p.refresh();
+ }
+ }
add(p);
patchSetPanelsList.add(p);
}
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/downloadIcon.png b/gerrit-gwtui/src/main/java/com/google/gerrit/client/downloadIcon.png
new file mode 100644
index 0000000..22ff495
--- /dev/null
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/downloadIcon.png
Binary files differ
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/gerrit.css b/gerrit-gwtui/src/main/java/com/google/gerrit/client/gerrit.css
index 533672e..7512d8c 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/gerrit.css
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/gerrit.css
@@ -1153,10 +1153,6 @@
margin-bottom: 10px;
}
-.createProjectLink {
- margin-bottom: 10px;
-}
-
.createProjectPanel {
margin-bottom: 10px;
background-color: trimColor;
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/patches/PatchConstants.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/patches/PatchConstants.java
index 70dcf75..4801e65 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/patches/PatchConstants.java
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/patches/PatchConstants.java
@@ -48,6 +48,9 @@
String fileList();
String expandComment();
+ String toggleReviewed();
+ String markAsReviewedAndGoToNext();
+
String commentEditorSet();
String commentInsert();
String commentSaveDraft();
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/patches/PatchConstants.properties b/gerrit-gwtui/src/main/java/com/google/gerrit/client/patches/PatchConstants.properties
index 694ccb4..11823ac 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/patches/PatchConstants.properties
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/patches/PatchConstants.properties
@@ -30,6 +30,9 @@
fileList = Browse files in patch set
expandComment = Expand or collapse comment
+toggleReviewed = Toggle the reviewed flag
+markAsReviewedAndGoToNext = Mark patch as reviewed and go to next unreviewed patch
+
commentEditorSet = Comment Editing
commentInsert = Create a new inline comment
commentSaveDraft = Save draft comment
@@ -45,7 +48,7 @@
reviewedAnd = Reviewed &
next = next
-download = (Download)
+download = Download
fileTypeSymlink = Type: Symbolic Link
fileTypeGitlink = Type: Git Commit in Subproject
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/patches/PatchScreen.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/patches/PatchScreen.java
index 0976a9d..4f8731c 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/patches/PatchScreen.java
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/patches/PatchScreen.java
@@ -25,8 +25,8 @@
import com.google.gerrit.client.rpc.GerritCallback;
import com.google.gerrit.client.rpc.ScreenLoadCallback;
import com.google.gerrit.client.ui.ChangeLink;
+import com.google.gerrit.client.ui.InlineHyperlink;
import com.google.gerrit.client.ui.ListenableAccountDiffPreference;
-import com.google.gerrit.client.ui.PatchLink;
import com.google.gerrit.client.ui.Screen;
import com.google.gerrit.common.data.PatchScript;
import com.google.gerrit.common.data.PatchSetDetail;
@@ -112,6 +112,7 @@
private CheckBox reviewedCheckBox;
private FlowPanel reviewedPanel;
+ private InlineHyperlink reviewedLink;
private HistoryTable historyTable;
private FlowPanel topPanel;
private FlowPanel contentPanel;
@@ -131,7 +132,9 @@
/** Keys that cause an action on this screen */
private KeyCommandSet keysNavigation;
+ private KeyCommandSet keysAction;
private HandlerRegistration regNavigation;
+ private HandlerRegistration regAction;
private boolean intralineFailure;
/**
@@ -193,13 +196,6 @@
Anchor reviewedAnchor = new Anchor("");
SafeHtml.set(reviewedAnchor, text);
- reviewedAnchor.addClickHandler(new ClickHandler() {
- @Override
- public void onClick(ClickEvent event) {
- setReviewedByCurrentUser(true);
- }
- });
-
final PatchValidator unreviewedValidator = new PatchValidator() {
public boolean isValid(Patch patch) {
return !patch.isReviewedByCurrentUser();
@@ -212,25 +208,20 @@
if (nextUnreviewedPatchIndex > -1) {
// Create invisible patch link to change page
- final PatchLink reviewedLink =
+ reviewedLink =
fileList.createLink(nextUnreviewedPatchIndex, getPatchScreenType(),
null, null);
reviewedLink.setText("");
- reviewedAnchor.addClickHandler(new ClickHandler() {
- @Override
- public void onClick(ClickEvent event) {
- reviewedLink.go();
- }
- });
} else {
- final ChangeLink upLink = new ChangeLink("", patchKey.getParentKey());
- reviewedAnchor.addClickHandler(new ClickHandler() {
- @Override
- public void onClick(ClickEvent event) {
- upLink.go();
- }
- });
+ reviewedLink = new ChangeLink("", patchKey.getParentKey());
}
+ reviewedAnchor.addClickHandler(new ClickHandler() {
+ @Override
+ public void onClick(ClickEvent event) {
+ setReviewedByCurrentUser(true);
+ reviewedLink.go();
+ }
+ });
return reviewedAnchor;
}
@@ -310,6 +301,14 @@
keysNavigation.add(new UpToChangeCommand(patchKey.getParentKey(), 0, 'u'));
keysNavigation.add(new FileListCmd(0, 'f', PatchUtil.C.fileList()));
+ if (Gerrit.isSignedIn()) {
+ keysAction = new KeyCommandSet(Gerrit.C.sectionActions());
+ keysAction
+ .add(new ToggleReviewedCmd(0, 'm', PatchUtil.C.toggleReviewed()));
+ keysAction.add(new MarkAsReviewedAndGoToNextCmd(0, 'M', PatchUtil.C
+ .markAsReviewedAndGoToNext()));
+ }
+
historyTable = new HistoryTable(this);
commitMessageBlock = new CommitMessageBlock();
@@ -393,6 +392,10 @@
regNavigation.removeHandler();
regNavigation = null;
}
+ if (regAction != null) {
+ regAction.removeHandler();
+ regAction = null;
+ }
super.onUnload();
}
@@ -405,6 +408,13 @@
regNavigation = null;
}
regNavigation = GlobalKey.add(this, keysNavigation);
+ if (regAction != null) {
+ regAction.removeHandler();
+ regAction = null;
+ }
+ if (keysAction != null) {
+ regAction = GlobalKey.add(this, keysAction);
+ }
}
protected abstract AbstractPatchContentTable createContentTable();
@@ -603,4 +613,31 @@
p.open();
}
}
+
+ public class ToggleReviewedCmd extends KeyCommand {
+ public ToggleReviewedCmd(int mask, int key, String help) {
+ super(mask, key, help);
+ }
+
+ @Override
+ public void onKeyPress(final KeyPressEvent event) {
+ final boolean isReviewed = !reviewedCheckBox.getValue();
+ reviewedCheckBox.setValue(isReviewed);
+ setReviewedByCurrentUser(isReviewed);
+ }
+ }
+
+ public class MarkAsReviewedAndGoToNextCmd extends KeyCommand {
+ public MarkAsReviewedAndGoToNextCmd(int mask, int key, String help) {
+ super(mask, key, help);
+ }
+
+ @Override
+ public void onKeyPress(final KeyPressEvent event) {
+ if (reviewedLink != null) {
+ setReviewedByCurrentUser(true);
+ reviewedLink.go();
+ }
+ }
+ }
}
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/patches/PatchSetSelectBox.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/patches/PatchSetSelectBox.java
index 5dd4e1f..5d4207f 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/patches/PatchSetSelectBox.java
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/patches/PatchSetSelectBox.java
@@ -21,16 +21,18 @@
import com.google.gerrit.reviewdb.client.Patch;
import com.google.gerrit.reviewdb.client.PatchSet;
import com.google.gwt.core.client.GWT;
-import com.google.gwt.dom.client.SpanElement;
+import com.google.gwt.dom.client.DivElement;
+import com.google.gwt.dom.client.Style.Display;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.resources.client.CssResource;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
+import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.ui.Anchor;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.HTMLPanel;
-import com.google.gwt.user.client.ui.Label;
+import com.google.gwt.user.client.ui.Image;
import com.google.gwtorm.client.KeyUtil;
import java.util.LinkedList;
@@ -46,6 +48,8 @@
String selected();
String hidden();
+
+ String downloadLink();
}
public enum Side {
@@ -68,7 +72,7 @@
BoxStyle style;
@UiField
- SpanElement sideMarker;
+ DivElement sideMarker;
public PatchSetSelectBox(Side side, final PatchScreen.Type type) {
this.side = side;
@@ -86,14 +90,24 @@
this.idActive = (side == Side.A) ? idSideA : idSideB;
this.links = new LinkedList<Anchor>();
+ linkPanel.clear();
+
if (screenType == PatchScreen.Type.UNIFIED) {
sideMarker.setInnerText((side == Side.A) ? "(-)" : "(+)");
+ } else {
+ sideMarker.getStyle().setDisplay(Display.NONE);
}
+ Anchor baseLink = null;
if (detail.getInfo().getParents().size() > 1) {
- addLink(PatchUtil.C.patchBaseAutoMerge(), null);
+ baseLink = createLink(PatchUtil.C.patchBaseAutoMerge(), null);
} else {
- addLink(PatchUtil.C.patchBase(), null);
+ baseLink = createLink(PatchUtil.C.patchBase(), null);
+ }
+
+ links.add(baseLink);
+ if (screenType == PatchScreen.Type.UNIFIED || side == Side.A) {
+ linkPanel.add(baseLink);
}
if (side == Side.B) {
@@ -102,7 +116,9 @@
for (Patch patch : script.getHistory()) {
PatchSet.Id psId = patch.getKey().getParentKey();
- addLink(Integer.toString(psId.get()), psId);
+ Anchor anchor = createLink(Integer.toString(psId.get()), psId);
+ links.add(anchor);
+ linkPanel.add(anchor);
}
if (idActive == null && side == Side.A) {
@@ -111,14 +127,13 @@
links.get(idActive.get()).setStyleName(style.selected());
}
- Anchor downloadLink = getDownloadLink();
+ Anchor downloadLink = createDownloadLink();
if (downloadLink != null) {
- linkPanel.add(new Label(" - "));
linkPanel.add(downloadLink);
}
}
- private void addLink(String label, final PatchSet.Id id) {
+ private Anchor createLink(String label, final PatchSet.Id id) {
final Anchor anchor = new Anchor(label);
anchor.addClickHandler(new ClickHandler() {
@Override
@@ -143,11 +158,10 @@
});
- links.add(anchor);
- linkPanel.add(anchor);
+ return anchor;
}
- private Anchor getDownloadLink() {
+ private Anchor createDownloadLink() {
boolean isCommitMessage = Patch.COMMIT_MSG.equals(script.getNewName());
if (isCommitMessage || (side == Side.A && 0 >= script.getA().size())
@@ -161,8 +175,14 @@
String sideURL = (side == Side.A) ? "1" : "0";
final String base = GWT.getHostPageBaseURL() + "cat/";
- final Anchor anchor = new Anchor(PatchUtil.C.download());
+ Image image = new Image(Gerrit.RESOURCES.downloadIcon());
+
+ final Anchor anchor = new Anchor();
anchor.setHref(base + KeyUtil.encode(key.toString()) + "^" + sideURL);
+ anchor.setTitle(PatchUtil.C.download());
+ anchor.setStyleName(style.downloadLink());
+ DOM.insertBefore(anchor.getElement(), image.getElement(),
+ DOM.getFirstChild(anchor.getElement()));
return anchor;
}
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/patches/PatchSetSelectBox.ui.xml b/gerrit-gwtui/src/main/java/com/google/gerrit/client/patches/PatchSetSelectBox.ui.xml
index 2c4bd5d..2fd183c 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/patches/PatchSetSelectBox.ui.xml
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/patches/PatchSetSelectBox.ui.xml
@@ -28,18 +28,21 @@
.wrapper {
width: 100%;
+ text-align: center;
+ font-size: 0; /* inline-block spacing fix */
}
- .patchSetLabel {
- font-weight: bold;
+ .linkPanel {
+ display: inline-block;
}
.linkPanel > div {
display: inline-block;
- padding: 3px;
+ float: left;
}
.linkPanel {
+ overflow: hidden; /* div clear fix */
font-size: 12px;
}
@@ -47,6 +50,27 @@
padding: 3px;
display: inline-block;
text-decoration: none;
+ float: left;
+ }
+
+ .patchSetLabel {
+ font-weight: bold;
+ float: left;
+ padding: 3px;
+ }
+
+ .sideMarker {
+ padding: 3px;
+ }
+
+ .downloadLink {
+ float: left;
+ padding: 1px !important;
+ margin-left: 3px;
+ }
+
+ .downloadLink > a {
+ text-size: 0;
}
.selected {
@@ -56,6 +80,7 @@
.sideMarker {
font-family: monospace;
+ float: left;
}
.hidden {
@@ -64,7 +89,10 @@
</ui:style>
<g:HTMLPanel styleName='wrapper'>
- <g:HTMLPanel styleName='{style.linkPanel}' ui:field='linkPanel'><span class='{style.patchSetLabel}'><ui:text from="{cons.patchSet}" /></span> <span class='{style.sideMarker}' ui:field='sideMarker'></span>: </g:HTMLPanel>
+ <g:HTMLPanel styleName='{style.linkPanel}' ui:field='linkPanel'>
+ <div class='{style.patchSetLabel}'><ui:text from="{cons.patchSet}" /></div>
+ <div class='{style.sideMarker}' ui:field='sideMarker'></div>
+ </g:HTMLPanel>
</g:HTMLPanel>
</ui:UiBinder>
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/patches/PatchTableHeaderSideBySide.ui.xml b/gerrit-gwtui/src/main/java/com/google/gerrit/client/patches/PatchTableHeaderSideBySide.ui.xml
index 424e6e5..d6fd717 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/patches/PatchTableHeaderSideBySide.ui.xml
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/patches/PatchTableHeaderSideBySide.ui.xml
@@ -26,6 +26,7 @@
width: 100%;
background-color: trimColor;
overflow: hidden;
+ font-size: 0; /* inline-block spacing fix */
}
.wrapper .box {
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/patches/PatchTableHeaderUnified.ui.xml b/gerrit-gwtui/src/main/java/com/google/gerrit/client/patches/PatchTableHeaderUnified.ui.xml
index e26e96a..24acfa3 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/patches/PatchTableHeaderUnified.ui.xml
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/patches/PatchTableHeaderUnified.ui.xml
@@ -24,6 +24,7 @@
.wrapper {
width: 100%;
background-color: trimColor;
+ font-size: 0; /* inline-block spacing fix */
}
.wrapper .box {
diff --git a/gerrit-httpd/src/main/java/com/google/gerrit/httpd/rpc/project/ReviewProjectAccess.java b/gerrit-httpd/src/main/java/com/google/gerrit/httpd/rpc/project/ReviewProjectAccess.java
index c422f6d..69a283a 100644
--- a/gerrit-httpd/src/main/java/com/google/gerrit/httpd/rpc/project/ReviewProjectAccess.java
+++ b/gerrit-httpd/src/main/java/com/google/gerrit/httpd/rpc/project/ReviewProjectAccess.java
@@ -19,6 +19,7 @@
import com.google.gerrit.reviewdb.client.Branch;
import com.google.gerrit.reviewdb.client.Change;
import com.google.gerrit.reviewdb.client.PatchSet;
+import com.google.gerrit.reviewdb.client.PatchSetAncestor;
import com.google.gerrit.reviewdb.client.PatchSetInfo;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gerrit.reviewdb.client.RevId;
@@ -31,17 +32,16 @@
import com.google.gerrit.server.git.ProjectConfig;
import com.google.gerrit.server.patch.AddReviewer;
import com.google.gerrit.server.patch.PatchSetInfoFactory;
-import com.google.gerrit.server.project.NoSuchProjectException;
import com.google.gerrit.server.project.ProjectControl;
import com.google.gwtorm.server.OrmException;
import com.google.inject.Inject;
import com.google.inject.assistedinject.Assisted;
-import org.eclipse.jgit.errors.ConfigInvalidException;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.revwalk.RevCommit;
import java.io.IOException;
+import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
@@ -81,36 +81,56 @@
@Override
protected Change.Id updateProjectConfig(ProjectConfig config, MetaDataUpdate md)
- throws IOException, NoSuchProjectException, ConfigInvalidException, OrmException {
- int nextChangeId = db.nextChangeId();
- PatchSet.Id patchSetId = new PatchSet.Id(new Change.Id(nextChangeId), 1);
- final PatchSet ps = new PatchSet(patchSetId);
+ throws IOException, OrmException {
+ Change.Id changeId = new Change.Id(db.nextChangeId());
+ PatchSet ps = new PatchSet(new PatchSet.Id(changeId, 1));
RevCommit commit = config.commitToNewRef(md, ps.getRefName());
if (commit.getId().equals(base)) {
return null;
}
- Change.Key changeKey = new Change.Key("I" + commit.name());
- final Change change =
- new Change(changeKey, new Change.Id(nextChangeId), user.getAccountId(),
- new Branch.NameKey(config.getProject().getNameKey(),
- GitRepositoryManager.REF_CONFIG));
+
+ Change change = new Change(
+ new Change.Key("I" + commit.name()),
+ changeId,
+ user.getAccountId(),
+ new Branch.NameKey(
+ config.getProject().getNameKey(),
+ GitRepositoryManager.REF_CONFIG));
change.nextPatchSetId();
ps.setCreatedOn(change.getCreatedOn());
- ps.setUploader(user.getAccountId());
+ ps.setUploader(change.getOwner());
ps.setRevision(new RevId(commit.name()));
- db.patchSets().insert(Collections.singleton(ps));
-
- final PatchSetInfo info = patchSetInfoFactory.get(commit, ps.getId());
+ PatchSetInfo info = patchSetInfoFactory.get(commit, ps.getId());
change.setCurrentPatchSet(info);
ChangeUtil.updated(change);
- db.changes().insert(Collections.singleton(change));
+ db.changes().beginTransaction(changeId);
+ try {
+ insertAncestors(ps.getId(), commit);
+ db.patchSets().insert(Collections.singleton(ps));
+ db.changes().insert(Collections.singleton(change));
+ addProjectOwnersAsReviewers(changeId);
+ db.commit();
+ } finally {
+ db.rollback();
+ }
+ return changeId;
+ }
- addProjectOwnersAsReviewers(change.getId());
+ private void insertAncestors(PatchSet.Id id, RevCommit src)
+ throws OrmException {
+ final int cnt = src.getParentCount();
+ List<PatchSetAncestor> toInsert = new ArrayList<PatchSetAncestor>(cnt);
+ for (int p = 0; p < cnt; p++) {
+ PatchSetAncestor a;
- return change.getId();
+ a = new PatchSetAncestor(new PatchSetAncestor.Id(id, p + 1));
+ a.setAncestorRevision(new RevId(src.getParent(p).name()));
+ toInsert.add(a);
+ }
+ db.patchSetAncestors().insert(toInsert);
}
private void addProjectOwnersAsReviewers(final Change.Id changeId) {
diff --git a/gerrit-prettify/src/main/java/com/google/gerrit/prettify/common/SparseFileContent.java b/gerrit-prettify/src/main/java/com/google/gerrit/prettify/common/SparseFileContent.java
index a5373b8..1a5468c 100644
--- a/gerrit-prettify/src/main/java/com/google/gerrit/prettify/common/SparseFileContent.java
+++ b/gerrit-prettify/src/main/java/com/google/gerrit/prettify/common/SparseFileContent.java
@@ -249,7 +249,7 @@
range.lines = lines;
SparseFileContent r = new SparseFileContent();
- r.setSize(size());
+ r.setSize(lines.size());
r.setMissingNewlineAtEnd(isMissingNewlineAtEnd());
r.setPath(getPath());
r.ranges.add(range);
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/ChangeUtil.java b/gerrit-server/src/main/java/com/google/gerrit/server/ChangeUtil.java
index 3868710..94b2169 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/ChangeUtil.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/ChangeUtil.java
@@ -14,6 +14,7 @@
package com.google.gerrit.server;
+import com.google.common.collect.Sets;
import com.google.gerrit.common.ChangeHookRunner;
import com.google.gerrit.common.ChangeHooks;
import com.google.gerrit.reviewdb.client.Account;
@@ -38,7 +39,6 @@
import com.google.gerrit.server.mail.ReplyToChangeSender;
import com.google.gerrit.server.mail.RevertedSender;
import com.google.gerrit.server.patch.PatchSetInfoFactory;
-import com.google.gerrit.server.patch.PatchSetInfoNotAvailableException;
import com.google.gerrit.server.project.ChangeControl;
import com.google.gerrit.server.project.InvalidChangeOperationException;
import com.google.gerrit.server.project.NoSuchChangeException;
@@ -68,6 +68,7 @@
import org.slf4j.LoggerFactory;
import java.io.IOException;
+import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
@@ -196,13 +197,15 @@
* Rebases a commit
*
* @param git Repository to find commits in
+ * @param inserter inserter to handle new trees and blobs.
* @param original The commit to rebase
* @param base Base to rebase against
* @return CommitBuilder the newly rebased commit
* @throws IOException Merged failed
*/
- public static CommitBuilder rebaseCommit(Repository git, RevCommit original,
- RevCommit base, PersonIdent committerIdent) throws IOException {
+ public static CommitBuilder rebaseCommit(Repository git,
+ final ObjectInserter inserter, RevCommit original, RevCommit base,
+ PersonIdent committerIdent) throws IOException {
if (original.getParentCount() == 0) {
throw new IOException(
@@ -222,6 +225,20 @@
}
final ThreeWayMerger merger = MergeStrategy.RESOLVE.newMerger(git, true);
+ merger.setObjectInserter(new ObjectInserter.Filter() {
+ @Override
+ protected ObjectInserter delegate() {
+ return inserter;
+ }
+
+ @Override
+ public void flush() {
+ }
+
+ @Override
+ public void release() {
+ }
+ });
merger.setBase(parentCommit);
merger.merge(original, base);
@@ -251,7 +268,7 @@
final ApprovalsUtil approvalsUtil) throws NoSuchChangeException,
EmailException, OrmException, MissingObjectException,
IncorrectObjectTypeException, IOException,
- PatchSetInfoNotAvailableException, InvalidChangeOperationException {
+ InvalidChangeOperationException {
final Change.Id changeId = patchSetId.getParentKey();
final ChangeControl changeControl =
@@ -319,104 +336,118 @@
branchTipCommit = revWalk.parseCommit(destRef.getObjectId());
}
- final RevCommit originalCommit =
- revWalk.parseCommit(ObjectId.fromString(originalPatchSet
- .getRevision().get()));
-
- CommitBuilder rebasedCommitBuilder =
- rebaseCommit(git, originalCommit, branchTipCommit, myIdent);
-
+ final RevCommit rebasedCommit;
final ObjectInserter oi = git.newObjectInserter();
- final ObjectId rebasedCommitId;
try {
- rebasedCommitId = oi.insert(rebasedCommitBuilder);
+ ObjectId oldId = ObjectId.fromString(originalPatchSet.getRevision().get());
+ ObjectId newId = oi.insert(rebaseCommit(
+ git, oi, revWalk.parseCommit(oldId), branchTipCommit, myIdent));
oi.flush();
+ rebasedCommit = revWalk.parseCommit(newId);
} finally {
oi.release();
}
- Change updatedChange =
- db.changes().atomicUpdate(changeId, new AtomicUpdate<Change>() {
- @Override
- public Change update(Change change) {
- if (change.getStatus().isOpen()) {
- change.nextPatchSetId();
- return change;
- } else {
- return null;
- }
- }
- });
+ change.nextPatchSetId();
+ final PatchSet newPatchSet = new PatchSet(change.currPatchSetId());
+ newPatchSet.setCreatedOn(new Timestamp(System.currentTimeMillis()));
+ newPatchSet.setUploader(user.getAccountId());
+ newPatchSet.setRevision(new RevId(rebasedCommit.name()));
- if (updatedChange == null) {
- throw new InvalidChangeOperationException("Change is closed: "
- + change.toString());
- } else {
- change = updatedChange;
- }
-
- final PatchSet rebasedPatchSet = new PatchSet(change.currPatchSetId());
- rebasedPatchSet.setCreatedOn(change.getCreatedOn());
- rebasedPatchSet.setUploader(user.getAccountId());
- rebasedPatchSet.setRevision(new RevId(rebasedCommitId.getName()));
-
- insertAncestors(db, rebasedPatchSet.getId(),
- revWalk.parseCommit(rebasedCommitId));
-
- db.patchSets().insert(Collections.singleton(rebasedPatchSet));
final PatchSetInfo info =
- patchSetInfoFactory.get(db, rebasedPatchSet.getId());
+ patchSetInfoFactory.get(rebasedCommit, newPatchSet.getId());
- change =
- db.changes().atomicUpdate(change.getId(),
- new AtomicUpdate<Change>() {
- @Override
- public Change update(Change change) {
- change.setCurrentPatchSet(info);
- ChangeUtil.updated(change);
- return change;
- }
- });
-
- final RefUpdate ru = git.updateRef(rebasedPatchSet.getRefName());
- ru.setNewObjectId(rebasedCommitId);
+ RefUpdate ru = git.updateRef(newPatchSet.getRefName());
+ ru.setExpectedOldObjectId(ObjectId.zeroId());
+ ru.setNewObjectId(rebasedCommit);
ru.disableRefLog();
if (ru.update(revWalk) != RefUpdate.Result.NEW) {
- throw new IOException("Failed to create ref "
- + rebasedPatchSet.getRefName() + " in " + git.getDirectory()
- + ": " + ru.getResult());
+ throw new IOException(String.format(
+ "Failed to create ref %s in %s: %s", newPatchSet.getRefName(),
+ change.getDest().getParentKey().get(), ru.getResult()));
}
-
replication.fire(change.getProject(), ru.getName());
- List<PatchSetApproval> patchSetApprovals = approvalsUtil.copyVetosToLatestPatchSet(change);
+ final Set<Account.Id> oldReviewers = Sets.newHashSet();
+ final Set<Account.Id> oldCC = Sets.newHashSet();
+ db.changes().beginTransaction(change.getId());
+ try {
+ Change updatedChange;
- final Set<Account.Id> oldReviewers = new HashSet<Account.Id>();
- final Set<Account.Id> oldCC = new HashSet<Account.Id>();
-
- for (PatchSetApproval a : patchSetApprovals) {
- if (a.getValue() != 0) {
- oldReviewers.add(a.getAccountId());
+ updatedChange = db.changes().atomicUpdate(changeId,
+ new AtomicUpdate<Change>() {
+ @Override
+ public Change update(Change change) {
+ if (change.getStatus().isOpen()) {
+ change.updateNumberOfPatchSets(newPatchSet.getPatchSetId());
+ return change;
+ } else {
+ return null;
+ }
+ }
+ });
+ if (updatedChange != null) {
+ change = updatedChange;
} else {
- oldCC.add(a.getAccountId());
+ throw new InvalidChangeOperationException(
+ String.format("Change %s is closed", change.getId()));
}
- }
- final ChangeMessage cmsg =
- new ChangeMessage(new ChangeMessage.Key(changeId,
- ChangeUtil.messageUUID(db)), user.getAccountId(), patchSetId);
- cmsg.setMessage("Patch Set " + patchSetId.get() + ": Rebased");
- db.changeMessages().insert(Collections.singleton(cmsg));
+ insertAncestors(db, newPatchSet.getId(), rebasedCommit);
+ db.patchSets().insert(Collections.singleton(newPatchSet));
+ updatedChange = db.changes().atomicUpdate(changeId,
+ new AtomicUpdate<Change>() {
+ @Override
+ public Change update(Change change) {
+ if (change.getStatus().isClosed()) {
+ return null;
+ }
+ if (!change.currentPatchSetId().equals(patchSetId)) {
+ return null;
+ }
+ if (change.getStatus() != Change.Status.DRAFT) {
+ change.setStatus(Change.Status.NEW);
+ }
+ change.setLastSha1MergeTested(null);
+ change.setCurrentPatchSet(info);
+ ChangeUtil.updated(change);
+ return change;
+ }
+ });
+ if (updatedChange != null) {
+ change = updatedChange;
+ } else {
+ throw new InvalidChangeOperationException(
+ String.format("Change %s was modified", change.getId()));
+ }
+
+ for (PatchSetApproval a : approvalsUtil.copyVetosToLatestPatchSet(change)) {
+ if (a.getValue() != 0) {
+ oldReviewers.add(a.getAccountId());
+ } else {
+ oldCC.add(a.getAccountId());
+ }
+ }
+
+ final ChangeMessage cmsg =
+ new ChangeMessage(new ChangeMessage.Key(changeId,
+ ChangeUtil.messageUUID(db)), user.getAccountId(), patchSetId);
+ cmsg.setMessage("Patch Set " + patchSetId.get() + ": Rebased");
+ db.changeMessages().insert(Collections.singleton(cmsg));
+ db.commit();
+ } finally {
+ db.rollback();
+ }
final ReplacePatchSetSender cm =
rebasedPatchSetSenderFactory.create(change);
cm.setFrom(user.getAccountId());
- cm.setPatchSet(rebasedPatchSet);
+ cm.setPatchSet(newPatchSet);
cm.addReviewers(oldReviewers);
cm.addExtraCC(oldCC);
cm.send();
- hooks.doPatchsetCreatedHook(change, rebasedPatchSet, db);
+ hooks.doPatchsetCreatedHook(change, newPatchSet, db);
} finally {
revWalk.release();
}
@@ -432,9 +463,7 @@
final PatchSetInfoFactory patchSetInfoFactory,
final GitReferenceUpdated replication, PersonIdent myIdent)
throws NoSuchChangeException, EmailException, OrmException,
- MissingObjectException, IncorrectObjectTypeException, IOException,
- PatchSetInfoNotAvailableException {
-
+ MissingObjectException, IncorrectObjectTypeException, IOException {
final Change.Id changeId = patchSetId.getParentKey();
final PatchSet patch = db.patchSets().get(patchSetId);
if (patch == null) {
@@ -446,7 +475,7 @@
git = gitManager.openRepository(db.changes().get(changeId).getProject());
} catch (RepositoryNotFoundException e) {
throw new NoSuchChangeException(changeId, e);
- };
+ }
final RevWalk revWalk = new RevWalk(git);
try {
@@ -459,54 +488,62 @@
RevCommit parentToCommitToRevert = commitToRevert.getParent(0);
revWalk.parseHeaders(parentToCommitToRevert);
- CommitBuilder revertCommit = new CommitBuilder();
- revertCommit.addParentId(commitToRevert);
- revertCommit.setTreeId(parentToCommitToRevert.getTree());
- revertCommit.setAuthor(authorIdent);
- revertCommit.setCommitter(myIdent);
+ CommitBuilder revertCommitBuilder = new CommitBuilder();
+ revertCommitBuilder.addParentId(commitToRevert);
+ revertCommitBuilder.setTreeId(parentToCommitToRevert.getTree());
+ revertCommitBuilder.setAuthor(authorIdent);
+ revertCommitBuilder.setCommitter(myIdent);
final ObjectId computedChangeId =
ChangeIdUtil.computeChangeId(parentToCommitToRevert.getTree(),
commitToRevert, authorIdent, myIdent, message);
- revertCommit.setMessage(ChangeIdUtil.insertId(message, computedChangeId, true));
+ revertCommitBuilder.setMessage(ChangeIdUtil.insertId(message, computedChangeId, true));
- final ObjectInserter oi = git.newObjectInserter();;
- ObjectId id;
+ RevCommit revertCommit;
+ final ObjectInserter oi = git.newObjectInserter();
try {
- id = oi.insert(revertCommit);
+ ObjectId id = oi.insert(revertCommitBuilder);
oi.flush();
+ revertCommit = revWalk.parseCommit(id);
} finally {
oi.release();
}
- Change.Key changeKey = new Change.Key("I" + computedChangeId.name());
- final Change change =
- new Change(changeKey, new Change.Id(db.nextChangeId()),
- user.getAccountId(), db.changes().get(changeId).getDest());
+ final Change change = new Change(
+ new Change.Key("I" + computedChangeId.name()),
+ new Change.Id(db.nextChangeId()),
+ user.getAccountId(),
+ db.changes().get(changeId).getDest());
change.nextPatchSetId();
final PatchSet ps = new PatchSet(change.currPatchSetId());
ps.setCreatedOn(change.getCreatedOn());
- ps.setUploader(user.getAccountId());
- ps.setRevision(new RevId(id.getName()));
+ ps.setUploader(change.getOwner());
+ ps.setRevision(new RevId(revertCommit.name()));
- db.patchSets().insert(Collections.singleton(ps));
-
- final PatchSetInfo info =
- patchSetInfoFactory.get(revWalk.parseCommit(id), ps.getId());
- change.setCurrentPatchSet(info);
+ change.setCurrentPatchSet(patchSetInfoFactory.get(revertCommit, ps.getId()));
ChangeUtil.updated(change);
- db.changes().insert(Collections.singleton(change));
final RefUpdate ru = git.updateRef(ps.getRefName());
- ru.setNewObjectId(id);
+ ru.setExpectedOldObjectId(ObjectId.zeroId());
+ ru.setNewObjectId(revertCommit);
ru.disableRefLog();
if (ru.update(revWalk) != RefUpdate.Result.NEW) {
- throw new IOException("Failed to create ref " + ps.getRefName()
- + " in " + git.getDirectory() + ": " + ru.getResult());
+ throw new IOException(String.format(
+ "Failed to create ref %s in %s: %s", ps.getRefName(),
+ change.getDest().getParentKey().get(), ru.getResult()));
}
- replication.fire(db.changes().get(changeId).getProject(),
- ru.getName());
+ replication.fire(change.getProject(), ru.getName());
+
+ db.changes().beginTransaction(change.getId());
+ try {
+ insertAncestors(db, ps.getId(), revertCommit);
+ db.patchSets().insert(Collections.singleton(ps));
+ db.changes().insert(Collections.singleton(change));
+ db.commit();
+ } finally {
+ db.rollback();
+ }
final ChangeMessage cmsg =
new ChangeMessage(new ChangeMessage.Key(changeId,
@@ -514,7 +551,7 @@
final StringBuilder msgBuf =
new StringBuilder("Patch Set " + patchSetId.get() + ": Reverted");
msgBuf.append("\n\n");
- msgBuf.append("This patchset was reverted in change: " + changeKey.get());
+ msgBuf.append("This patchset was reverted in change: " + change.getKey().get());
cmsg.setMessage(msgBuf.toString());
db.changeMessages().insert(Collections.singleton(cmsg));
@@ -596,7 +633,7 @@
public static <T extends ReplyToChangeSender> void updatedChange(
final ReviewDb db, final IdentifiedUser user, final Change change,
final ChangeMessage cmsg, ReplyToChangeSender.Factory<T> senderFactory)
- throws NoSuchChangeException, EmailException, OrmException {
+ throws OrmException {
db.changeMessages().insert(Collections.singleton(cmsg));
new ApprovalsUtil(db, null).syncChangeStatus(change);
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/git/ReceiveCommits.java b/gerrit-server/src/main/java/com/google/gerrit/server/git/ReceiveCommits.java
index 9571f39..ccf7c2d 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/git/ReceiveCommits.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/git/ReceiveCommits.java
@@ -613,10 +613,10 @@
if (replace.inputCommand == newChange) {
replaceCount++;
- if (replace.cmd.getResult() == OK) {
+ if (replace.cmd != null && replace.cmd.getResult() == OK) {
okToInsert++;
}
- } else if (replace.cmd.getResult() == OK) {
+ } else if (replace.cmd != null && replace.cmd.getResult() == OK) {
try {
if (replace.insertPatchSet().checkedGet() != null) {
replace.inputCommand.setResult(OK);
@@ -856,7 +856,7 @@
} else {
errors.put(Error.UPDATE, ctl.getRefName());
}
- reject(cmd, "can not update the reference as a fast forward");
+ reject(cmd);
}
}
@@ -1318,6 +1318,9 @@
final List<FooterLine> footerLines = commit.getFooterLines();
for (final FooterLine footerLine : footerLines) {
try {
+ if (ps.isDraft()) {
+ continue;
+ }
if (isReviewer(footerLine)) {
reviewers.add(toAccountId(footerLine.getValue().trim()));
} else if (footerLine.matches(FooterKey.CC)) {
@@ -1406,7 +1409,7 @@
}
for (ReplaceRequest req : replaceByChange.values()) {
- if (req.inputCommand.getResult() == NOT_ATTEMPTED) {
+ if (req.inputCommand.getResult() == NOT_ATTEMPTED && req.cmd != null) {
batch.addCommand(req.cmd);
}
}
@@ -1414,7 +1417,7 @@
if (newChange != null && newChange.getResult() != NOT_ATTEMPTED) {
// Cancel creations tied to refs/for/ or refs/drafts/ command.
for (ReplaceRequest req : replaceByChange.values()) {
- if (req.inputCommand == newChange) {
+ if (req.inputCommand == newChange && req.cmd != null) {
req.cmd.setResult(Result.REJECTED_OTHER_REASON, "aborted");
}
}
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/git/VersionedMetaData.java b/gerrit-server/src/main/java/com/google/gerrit/server/git/VersionedMetaData.java
index 44536e2..e9c5536 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/git/VersionedMetaData.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/git/VersionedMetaData.java
@@ -254,6 +254,8 @@
RefUpdate ru = db.updateRef(refName);
ru.setExpectedOldObjectId(ObjectId.zeroId());
ru.setNewObjectId(src);
+ ru.disableRefLog();
+ inserter.flush();
RefUpdate.Result result = ru.update();
switch (result) {
case NEW:
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/query/change/ListChanges.java b/gerrit-server/src/main/java/com/google/gerrit/server/query/change/ListChanges.java
index a900175..f0ed66a 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/query/change/ListChanges.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/query/change/ListChanges.java
@@ -349,6 +349,10 @@
}
PatchSet ps = cd.currentPatchSet(db);
+ if (ps == null) {
+ return Collections.emptyMap();
+ }
+
Map<String, LabelInfo> labels = Maps.newLinkedHashMap();
for (SubmitRecord rec : ctl.canSubmit(db.get(), ps, cd, true, false)) {
if (rec.labels == null) {
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/util/ThreadLocalRequestScopePropagator.java b/gerrit-server/src/main/java/com/google/gerrit/server/util/ThreadLocalRequestScopePropagator.java
index e465247..7728d6f 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/util/ThreadLocalRequestScopePropagator.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/util/ThreadLocalRequestScopePropagator.java
@@ -45,19 +45,16 @@
return new Callable<T>() {
@Override
public T call() throws Exception {
- if (threadLocal.get() != null) {
- // This is consistent with the Guice ServletScopes.continueRequest()
- // behavior.
- throw new IllegalStateException("Cannot continue request, "
- + "thread already has request in progress. A new thread must "
- + "be used to propagate the request scope context.");
- }
-
+ C old = threadLocal.get();
threadLocal.set(ctx);
try {
return callable.call();
} finally {
- threadLocal.remove();
+ if (old != null) {
+ threadLocal.set(old);
+ } else {
+ threadLocal.remove();
+ }
}
}
};