Merge "Use ApprovalsUtil.addReviewers() for PostReviewers"
diff --git a/Documentation/access-control.txt b/Documentation/access-control.txt
index b6f7d7c..facc8f2 100644
--- a/Documentation/access-control.txt
+++ b/Documentation/access-control.txt
@@ -542,13 +542,12 @@
 configuration.  Users who are members of an owner group can:
 
 * Change the project description
-* Create/delete a branch through the web UI (not SSH)
+* Create a branch through SSH
+* Create/delete a branch through the web UI
 * Grant/revoke any access rights, including `Owner`
 
-Note that project owners implicitly have branch creation or deletion
-through the web UI, but not through SSH.  To get SSH branch access
-project owners must grant an access right to a group they are a
-member of, just like for any other user.
+To get SSH branch access project owners must grant an access right to a group
+they are a member of, just like for any other user.
 
 Ownership over a particular branch subspace may be delegated by
 entering a branch pattern.  To delegate control over all branches
diff --git a/Documentation/cmd-create-branch.txt b/Documentation/cmd-create-branch.txt
new file mode 100644
index 0000000..6e6d561
--- /dev/null
+++ b/Documentation/cmd-create-branch.txt
@@ -0,0 +1,58 @@
+gerrit create-branch
+====================
+
+NAME
+----
+gerrit create-branch - Create a new branch
+
+SYNOPSIS
+--------
+--
+'ssh' -p <port> <host> 'gerrit create-branch'
+  <PROJECT>
+  <NAME>
+  <REVISION>
+--
+
+DESCRIPTION
+-----------
+Creates a new branch for a project.
+
+ACCESS
+------
+Caller should have link:access-control.html#category_create[Create Reference]
+permission on the project.
+
+Administrators do not automatically have permission to create branches. It must
+be granted via the Create Reference permission.
+
+SCRIPTING
+---------
+This command is intended to be used in scripts.
+
+OPTIONS
+-------
+<PROJECT>::
+    Required; name of the project.
+
+<NAME>::
+    Required; name of the branch to be created.
+
+<REVISION>::
+    Required; base revision of the new branch.
+
+EXAMPLES
+--------
+Create a new branch called 'newbranch' from the 'master' branch of
+the project 'myproject'.
+
+====
+    $ ssh -p 29418 review.example.com gerrit create-branch myproject newbranch master
+====
+
+GERRIT
+------
+Part of link:index.html[Gerrit Code Review]
+
+SEARCHBOX
+---------
diff --git a/Documentation/cmd-index.txt b/Documentation/cmd-index.txt
index 4e62451..6ddfa36 100644
--- a/Documentation/cmd-index.txt
+++ b/Documentation/cmd-index.txt
@@ -96,6 +96,9 @@
 Also implements the magic associated with uploading commits for
 review.  See link:user-upload.html#push_create[Creating Changes].
 
+link:cmd-create-branch.html[gerrit create-branch]::
+	Create a new project branch.
+
 [[admin_commands]]Administrator Commands
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
diff --git a/Documentation/dev-buck.txt b/Documentation/dev-buck.txt
index 611d64d..7b4981a 100644
--- a/Documentation/dev-buck.txt
+++ b/Documentation/dev-buck.txt
@@ -7,7 +7,7 @@
 
 There is currently no binary distribution of Buck, so it has to be manually
 built and installed.  Apache Ant is required.  Currently only Linux and Mac
-OS are supported.
+OS are supported.  Gerrit's buck wrappers require Python version 2.6 or higher.
 
 Clone the git and build it:
 
@@ -130,7 +130,7 @@
 ----
 
 Java binaries, Java sources and Java docs are generated into corresponding
-project directories in buck-out/gen, here as example for plugin API:
+project directories in `buck-out/gen`, here as example for plugin API:
 
 ----
   buck-out/gen/gerrit-plugin-api/plugin-api.jar
@@ -144,7 +144,7 @@
   buck build api_install
 ----
 
-Deploy {extension,plugin,gwt}-api to the remote maven repository
+Deploy {extension,plugin,gwt}-api to the remote maven repository:
 
 ----
   buck build api_deploy
@@ -154,6 +154,11 @@
 * 2.9-SNAPSHOT: snapshot repo
 * 2.9: release repo
 
+Deploying to the remote repository still depends on Maven, and the credentials
+for the repository need to be
+link:dev-release-deploy-config.html#deploy-configuration-settings-xml[
+configured in Maven's settings.xml file].
+
 Plugins
 ~~~~~~~
 
diff --git a/Documentation/dev-readme.txt b/Documentation/dev-readme.txt
index e73e039..10455c0 100644
--- a/Documentation/dev-readme.txt
+++ b/Documentation/dev-readme.txt
@@ -28,6 +28,23 @@
 link:dev-buck.html#build[Building on the command line with Buck].
 
 
+Switching between branches
+--------------------------
+
+When switching between branches with `git checkout`, be aware that
+submodule revisions are not altered.  This may result in the wrong
+plugin revisions being present, unneeded plugins being present, or
+expected plugins being missing.
+
+After switching branches, make sure the submodules are at the correct
+revisions for the new branch with the commands:
+
+----
+  git submodule update
+  git clean -fdx
+----
+
+
 Configuring Eclipse
 -------------------
 
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 5bb207d..0020647 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
@@ -199,8 +199,10 @@
   String projectFilterPanel();
   String projectNameColumn();
   String publishCommentsScreen();
-  String relatedChangesTabPanel();
+  String relatedChangesGitweb();
+  String relatedChangesNotCurrent();
   String relatedChangesSubject();
+  String relatedChangesTabPanel();
   String registerScreenExplain();
   String registerScreenNextLinks();
   String registerScreenSection();
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/change/RelatedChanges.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/change/RelatedChanges.java
index f98e8b4..0d46f8f 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/change/RelatedChanges.java
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/change/RelatedChanges.java
@@ -330,18 +330,27 @@
     final native boolean has_revision_number()
     /*-{ return this.hasOwnProperty('_revision_number') }-*/;
 
+    final native boolean has_current_revision_number()
+    /*-{ return this.hasOwnProperty('_current_revision_number') }-*/;
+
     final native int _change_number()
     /*-{ return this._change_number }-*/;
 
     final native int _revision_number()
     /*-{ return this._revision_number }-*/;
 
+    final native int _current_revision_number()
+    /*-{ return this._current_revision_number }-*/;
+
     final native void set_change_number(int n)
     /*-{ this._change_number=n; }-*/;
 
     final native void set_revision_number(int n)
     /*-{ this._revision_number=n; }-*/;
 
+    final native void set_current_revision_number(int n)
+    /*-{ this._current_revision_number=n; }-*/;
+
     protected ChangeAndCommit() {
     }
   }
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/change/RelatedChangesTab.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/change/RelatedChangesTab.java
index 162471e..5e3cb03 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/change/RelatedChangesTab.java
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/change/RelatedChangesTab.java
@@ -17,6 +17,7 @@
 import com.google.gerrit.client.Gerrit;
 import com.google.gerrit.client.GitwebLink;
 import com.google.gerrit.client.change.RelatedChanges.ChangeAndCommit;
+import com.google.gerrit.client.changes.Util;
 import com.google.gerrit.client.ui.NavigationTable;
 import com.google.gerrit.common.PageLinks;
 import com.google.gerrit.reviewdb.client.PatchSet;
@@ -278,6 +279,18 @@
       }
       sb.closeTd();
 
+      sb.openTd();
+      GitwebLink gw = Gerrit.getGitwebLink();
+      if (gw != null && (!info.has_change_number() || !info.has_revision_number())) {
+        sb.addStyleName(Gerrit.RESOURCES.css().relatedChangesGitweb());
+        sb.setAttribute("title", gw.getLinkName());
+      } else if (info.has_current_revision_number() && info.has_revision_number()
+          && info._current_revision_number() != info._revision_number()) {
+        sb.addStyleName(Gerrit.RESOURCES.css().relatedChangesNotCurrent());
+        sb.setAttribute("title", Util.C.notCurrent());
+      }
+      sb.closeTd();
+
       sb.closeTr();
     }
 
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/diff/CommentBoxUi.css b/gerrit-gwtui/src/main/java/com/google/gerrit/client/diff/CommentBoxUi.css
index 351442b..ffce7e6 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/diff/CommentBoxUi.css
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/diff/CommentBoxUi.css
@@ -25,6 +25,11 @@
   box-shadow: 3px 3px 3px #888888;
   margin-bottom: 5px;
   margin-right: 5px;
+  -webkit-touch-callout: initial;
+  -webkit-user-select: initial;
+  -khtml-user-select: initial;
+  -moz-user-select: initial;
+  -ms-user-select: initial;
 }
 
 .header { cursor: pointer; }
@@ -80,3 +85,16 @@
   white-space: nowrap;
   color: #fff;
 }
+
+@sprite .go_prev {
+  gwt-image: "go_prev";
+  display: inline-block;
+}
+@sprite .go_next {
+  gwt-image: "go_next";
+  display: inline-block;
+}
+@sprite .go_up {
+  gwt-image: "go_up";
+  display: inline-block;
+}
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/diff/DiffTable.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/diff/DiffTable.java
index 17bacc6..e4ddebd 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/diff/DiffTable.java
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/diff/DiffTable.java
@@ -37,6 +37,7 @@
   private static final Binder uiBinder = GWT.create(Binder.class);
 
   interface DiffTableStyle extends CssResource {
+    String insertCommentIcon();
     String fullscreen();
     String intralineBg();
     String diff();
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/diff/DiffTable.ui.xml b/gerrit-gwtui/src/main/java/com/google/gerrit/client/diff/DiffTable.ui.xml
index 02bb499..f314849 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/diff/DiffTable.ui.xml
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/diff/DiffTable.ui.xml
@@ -23,11 +23,24 @@
     @external .cm-keymap-fat-cursor, CodeMirror-cursor;
     @external .cm-searching, .cm-trailingspace, .cm-tab;
 
+    .insertCommentIcon {
+      cursor: pointer;
+      position: absolute;
+      z-index: 150;
+    }
     .fullscreen {
+      background-color: #f7f7f7;
       border-bottom: 1px solid #ddd;
     }
 
-    .difftable { max-width: 1484px; }
+    .difftable {
+      max-width: 1484px;
+      -webkit-touch-callout: none;
+      -webkit-user-select: none;
+      -khtml-user-select: none;
+      -moz-user-select: none;
+      -ms-user-select: none;
+    }
     .difftable .CodeMirror-lines { padding: 0; }
     .difftable .CodeMirror pre {
       padding: 0;
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/diff/Header.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/diff/Header.java
index b2a6fd9..9292463 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/diff/Header.java
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/diff/Header.java
@@ -34,6 +34,7 @@
 import com.google.gwt.core.client.JsArrayString;
 import com.google.gwt.dom.client.Element;
 import com.google.gwt.dom.client.Style.Visibility;
+import com.google.gwt.event.dom.client.ClickEvent;
 import com.google.gwt.event.dom.client.KeyPressEvent;
 import com.google.gwt.event.logical.shared.ValueChangeEvent;
 import com.google.gwt.uibinder.client.UiBinder;
@@ -43,6 +44,7 @@
 import com.google.gwt.user.client.ui.CheckBox;
 import com.google.gwt.user.client.ui.Composite;
 import com.google.gwt.user.client.ui.HTMLPanel;
+import com.google.gwt.user.client.ui.Image;
 import com.google.gwt.user.client.ui.UIObject;
 import com.google.gwtexpui.globalkey.client.KeyCommand;
 import com.google.gwtexpui.globalkey.client.KeyCommandSet;
@@ -52,6 +54,9 @@
 class Header extends Composite {
   interface Binder extends UiBinder<HTMLPanel, Header> {}
   private static final Binder uiBinder = GWT.create(Binder.class);
+  static {
+    Resources.I.style().ensureInjected();
+  }
 
   @UiField CheckBox reviewed;
   @UiField Element project;
@@ -62,6 +67,7 @@
   @UiField InlineHyperlink prev;
   @UiField InlineHyperlink up;
   @UiField InlineHyperlink next;
+  @UiField Image preferences;
 
   private final KeyCommandSet keys;
   private final PatchSet.Id base;
@@ -70,6 +76,7 @@
   private boolean hasPrev;
   private boolean hasNext;
   private String nextPath;
+  private PreferencesAction prefsAction;
 
   Header(KeyCommandSet keys, PatchSet.Id base, PatchSet.Id patchSetId,
       String path) {
@@ -151,10 +158,15 @@
     }
   }
 
-  void set(ChangeInfo info) {
+  void setChangeInfo(ChangeInfo info) {
     project.setInnerText(info.project());
   }
 
+  void init(PreferencesAction pa) {
+    prefsAction = pa;
+    prefsAction.setPartner(preferences);
+  }
+
   void setReviewed(boolean r) {
     reviewed.setValue(r, true);
   }
@@ -176,6 +188,11 @@
     }
   }
 
+  @UiHandler("preferences")
+  void onPreferences(ClickEvent e) {
+    prefsAction.show();
+  }
+
   private String url(FileInfo info) {
     return info.binary()
       ? Dispatcher.toUnified(base, patchSetId, info.path())
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/diff/Header.ui.xml b/gerrit-gwtui/src/main/java/com/google/gerrit/client/diff/Header.ui.xml
index 306109c7..b812f63 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/diff/Header.ui.xml
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/diff/Header.ui.xml
@@ -18,9 +18,12 @@
     xmlns:ui='urn:ui:com.google.gwt.uibinder'
     xmlns:g='urn:import:com.google.gwt.user.client.ui'
     xmlns:x='urn:import:com.google.gerrit.client.ui'>
+  <ui:with field='res' type='com.google.gerrit.client.diff.Resources'/>
   <ui:style>
   .header {
     position: relative;
+    height: 16px;
+    line-height: 16px;
     max-width: 1484px;
   }
   .reviewed input {
@@ -29,12 +32,13 @@
     vertical-align: middle;
   }
   .path {
-    white-space: no-wrap;
+    white-space: nowrap;
   }
   .navigation {
     position: absolute;
     top: 0;
     right: 15px;
+    height: 16px;
     font-family: Arial Unicode MS, sans-serif;
   }
   .nodiff {
@@ -56,12 +60,18 @@
     </span>
 
     <div class='{style.navigation}'>
-      <x:InlineHyperlink ui:field='prev'>&#x21e6;</x:InlineHyperlink>
-      <x:InlineHyperlink ui:field='up' title='Up to change (Shortcut: u)'>
+      <x:InlineHyperlink ui:field='prev' styleName='{res.style.go_prev}'/>
+      <x:InlineHyperlink ui:field='up'
+          styleName='{res.style.go_up}'
+          title='Up to change (Shortcut: u)'>
         <ui:attribute name='title'/>
-        &#x21e7;
       </x:InlineHyperlink>
-      <x:InlineHyperlink ui:field='next'>&#x21e8;</x:InlineHyperlink>
+      <x:InlineHyperlink ui:field='next' styleName='{res.style.go_next}'/>
+      <g:Image ui:field='preferences'
+           resource='{res.gear}'
+           title='Diff preferences (Shortcut: ,)'>
+         <ui:attribute name='title'/>
+      </g:Image>
     </div>
   </g:HTMLPanel>
-</ui:UiBinder>
\ No newline at end of file
+</ui:UiBinder>
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/diff/PreferencesAction.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/diff/PreferencesAction.java
index 68a24f5..d5d3d8d 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/diff/PreferencesAction.java
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/diff/PreferencesAction.java
@@ -19,12 +19,14 @@
 import com.google.gwt.event.logical.shared.CloseHandler;
 import com.google.gwt.user.client.ui.PopupPanel;
 import com.google.gwt.user.client.ui.PopupPanel.PositionCallback;
+import com.google.gwt.user.client.ui.Widget;
 
 class PreferencesAction {
   private final SideBySide2 view;
   private final DiffPreferences prefs;
   private PopupPanel popup;
   private PreferencesBox current;
+  private Widget partner;
 
   PreferencesAction(SideBySide2 view, DiffPreferences prefs) {
     this.view = view;
@@ -50,6 +52,7 @@
     popup = new PopupPanel(true, false);
     popup.setStyleName(current.style.dialog());
     popup.add(current);
+    popup.addAutoHidePartner(partner.getElement());
     popup.addCloseHandler(new CloseHandler<PopupPanel>() {
       @Override
       public void onClose(CloseEvent<PopupPanel> event) {
@@ -61,7 +64,7 @@
     popup.setPopupPositionAndShow(new PositionCallback() {
       @Override
       public void setPosition(int offsetWidth, int offsetHeight) {
-        popup.setPopupPosition(390, 120);
+        popup.setPopupPosition(300, 120);
       }
     });
     current.setFocus(true);
@@ -74,4 +77,8 @@
       current = null;
     }
   }
+
+  void setPartner(Widget w) {
+    partner = w;
+  }
 }
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/diff/Resources.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/diff/Resources.java
index b7840c2..5356f2c 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/diff/Resources.java
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/diff/Resources.java
@@ -17,12 +17,17 @@
 import com.google.gwt.core.client.GWT;
 import com.google.gwt.resources.client.ClientBundle;
 import com.google.gwt.resources.client.CssResource;
+import com.google.gwt.resources.client.ImageResource;
 
 /** Resources used by diff. */
 interface Resources extends ClientBundle {
   static final Resources I = GWT.create(Resources.class);
 
   @Source("CommentBoxUi.css") Style style();
+  @Source("go-prev.png") ImageResource go_prev();
+  @Source("go-next.png") ImageResource go_next();
+  @Source("go-up.png") ImageResource go_up();
+  @Source("gear.png") ImageResource gear();
 
   interface Style extends CssResource {
     String commentBox();
@@ -30,5 +35,9 @@
     String header();
     String summary();
     String date();
+
+    String go_prev();
+    String go_next();
+    String go_up();
   }
 }
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/diff/SideBySide2.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/diff/SideBySide2.java
index fea1909..7d16915 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/diff/SideBySide2.java
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/diff/SideBySide2.java
@@ -54,7 +54,10 @@
 import com.google.gwt.core.client.Scheduler.ScheduledCommand;
 import com.google.gwt.dom.client.Element;
 import com.google.gwt.dom.client.NativeEvent;
+import com.google.gwt.dom.client.Style;
 import com.google.gwt.dom.client.Style.Unit;
+import com.google.gwt.event.dom.client.ClickEvent;
+import com.google.gwt.event.dom.client.ClickHandler;
 import com.google.gwt.event.dom.client.KeyCodes;
 import com.google.gwt.event.dom.client.KeyPressEvent;
 import com.google.gwt.event.logical.shared.ResizeEvent;
@@ -65,6 +68,7 @@
 import com.google.gwt.user.client.Window;
 import com.google.gwt.user.client.rpc.AsyncCallback;
 import com.google.gwt.user.client.ui.FlowPanel;
+import com.google.gwt.user.client.ui.Image;
 import com.google.gwt.user.client.ui.SimplePanel;
 import com.google.gwt.user.client.ui.Widget;
 import com.google.gwtexpui.globalkey.client.GlobalKey;
@@ -73,6 +77,7 @@
 import com.google.gwtexpui.globalkey.client.ShowHelpCommand;
 
 import net.codemirror.lib.CodeMirror;
+import net.codemirror.lib.CodeMirror.BeforeSelectionChangeHandler;
 import net.codemirror.lib.CodeMirror.GutterClickHandler;
 import net.codemirror.lib.CodeMirror.LineClassWhere;
 import net.codemirror.lib.CodeMirror.LineHandle;
@@ -83,6 +88,7 @@
 import net.codemirror.lib.LineCharacter;
 import net.codemirror.lib.LineWidget;
 import net.codemirror.lib.ModeInjector;
+import net.codemirror.lib.Rect;
 import net.codemirror.lib.TextMarker;
 import net.codemirror.lib.TextMarker.FromTo;
 
@@ -226,7 +232,7 @@
         JsArray<RevisionInfo> list = info.revisions().values();
         RevisionInfo.sortRevisionInfoByNumber(list);
         diffTable.setUpPatchSetNav(list, diff);
-        header.set(info);
+        header.setChangeInfo(info);
       }}));
 
     ConfigInfoCache.get(changeId, group.addFinal(
@@ -314,6 +320,7 @@
   }
 
   private void registerCmEvents(final CodeMirror cm) {
+    cm.on("beforeSelectionChange", onSelectionChange(cm));
     cm.on("cursorActivity", updateActiveLine(cm));
     cm.on("gutterClick", onGutterClick(cm));
     cm.on("renderLine", resizeLinePadding(getSideFromCm(cm)));
@@ -399,6 +406,47 @@
         .on("Shift-Right", flipCursorSide(cm, false)));
   }
 
+  private BeforeSelectionChangeHandler onSelectionChange(final CodeMirror cm) {
+    return new BeforeSelectionChangeHandler() {
+      private Image icon;
+
+      @Override
+      public void handle(CodeMirror cm, LineCharacter anchor, LineCharacter head) {
+        if (anchor == head
+            || (anchor.getLine() == head.getLine()
+             && anchor.getCh() == head.getCh())) {
+          if (icon != null) {
+            icon.setVisible(false);
+          }
+          return;
+        } else if (icon == null) {
+          init(anchor);
+        }
+
+        icon.setVisible(true);
+        Rect r = cm.charCoords(head, "local");
+        Style s = icon.getElement().getStyle();
+        s.setTop((int) (r.top() - icon.getOffsetHeight() + 2), Unit.PX);
+        s.setLeft((int) (r.right() - icon.getOffsetWidth() / 2), Unit.PX);
+      }
+
+      private void init(LineCharacter anchor) {
+        icon = new Image(Gerrit.RESOURCES.draftComments());
+        icon.setTitle(PatchUtil.C.commentInsert());
+        icon.setStyleName(DiffTable.style.insertCommentIcon());
+        icon.addClickHandler(new ClickHandler() {
+          @Override
+          public void onClick(ClickEvent event) {
+            icon.setVisible(false);
+            insertNewDraft(cm).run();
+          }
+        });
+        add(icon);
+        cm.addWidget(anchor, icon.getElement(), false);
+      }
+    };
+  }
+
   @Override
   public void registerKeys() {
     super.registerKeys();
@@ -533,6 +581,7 @@
     prefsAction = new PreferencesAction(this, prefs);
     scrollingGlue = GWT.create(ScrollSynchronizer.class);
     scrollingGlue.init(diffTable, cmA, cmB, mapper);
+    header.init(prefsAction);
     resizeHandler = Window.addResizeHandler(new ResizeHandler() {
       @Override
       public void onResize(ResizeEvent event) {
@@ -1285,6 +1334,7 @@
         if (cm.somethingSelected()) {
           lineActiveBoxMap.put(handle,
               addNewDraft(cm, line, fromTo.getTo().getLine() == line ? fromTo : null));
+          cm.setSelection(cm.getCursor());
         } else if (box == null) {
           lineActiveBoxMap.put(handle, addNewDraft(cm, line, null));
         } else if (box instanceof DraftBox) {
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/diff/SkipBar.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/diff/SkipBar.java
index 0f9a5cb..4adb9cc 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/diff/SkipBar.java
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/diff/SkipBar.java
@@ -133,6 +133,7 @@
   void expandAll() {
     clearMarkerAndWidget();
     removeFromParent();
+    updateSelection();
   }
 
   private void expandBefore() {
@@ -148,6 +149,7 @@
         .set("noHScroll", true);
     setWidget(cm.addLineWidget(newStart - 1, getElement(), config));
     updateSkipNum();
+    updateSelection();
   }
 
   private void expandAfter() {
@@ -167,6 +169,14 @@
       setWidget(cm.addLineWidget(newEnd + 1, getElement(), config));
     }
     updateSkipNum();
+    updateSelection();
+  }
+
+  private void updateSelection() {
+    if (cm.somethingSelected()) {
+      FromTo sel = cm.getSelectedRange();
+      cm.setSelection(sel.getFrom(), sel.getTo());
+    }
   }
 
   @UiHandler("skipNum")
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/diff/gear.png b/gerrit-gwtui/src/main/java/com/google/gerrit/client/diff/gear.png
new file mode 100644
index 0000000..d90ab66
--- /dev/null
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/diff/gear.png
Binary files differ
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/diff/go-next.png b/gerrit-gwtui/src/main/java/com/google/gerrit/client/diff/go-next.png
new file mode 100644
index 0000000..6ef8de7
--- /dev/null
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/diff/go-next.png
Binary files differ
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/diff/go-prev.png b/gerrit-gwtui/src/main/java/com/google/gerrit/client/diff/go-prev.png
new file mode 100644
index 0000000..659cd90
--- /dev/null
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/diff/go-prev.png
Binary files differ
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/diff/go-up.png b/gerrit-gwtui/src/main/java/com/google/gerrit/client/diff/go-up.png
new file mode 100644
index 0000000..fa9a7d7
--- /dev/null
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/diff/go-up.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 9c8ec57..029dd3b 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
@@ -1642,3 +1642,11 @@
 .relatedChangesTabPanel .gwt-TabBarItem-disabled {
   display: none;
 }
+.relatedChangesNotCurrent:after {
+  content: '\25CF'; /* circle */
+  color: #FFA62F;   /* orange */
+}
+.relatedChangesGitweb:after {
+  content: '\25CF'; /* circle */
+  color: #000;
+}
diff --git a/gerrit-gwtui/src/main/java/net/codemirror/lib/CodeMirror.java b/gerrit-gwtui/src/main/java/net/codemirror/lib/CodeMirror.java
index 6ff6f72..712f268 100644
--- a/gerrit-gwtui/src/main/java/net/codemirror/lib/CodeMirror.java
+++ b/gerrit-gwtui/src/main/java/net/codemirror/lib/CodeMirror.java
@@ -138,6 +138,10 @@
     return this.heightAtLine(line, mode);
   }-*/;
 
+  public final native Rect charCoords(LineCharacter pos, String mode) /*-{
+    return this.charCoords(pos, mode);
+  }-*/;
+
   public final native CodeMirrorDoc getDoc() /*-{
     return this.getDoc();
   }-*/;
@@ -197,6 +201,12 @@
     }));
   }-*/;
 
+  public final native void on(String event, BeforeSelectionChangeHandler handler) /*-{
+    this.on(event, $entry(function(cm, e) {
+      handler.@net.codemirror.lib.CodeMirror.BeforeSelectionChangeHandler::handle(Lnet/codemirror/lib/CodeMirror;Lnet/codemirror/lib/LineCharacter;Lnet/codemirror/lib/LineCharacter;)(cm,e.anchor,e.head);
+    }));
+  }-*/;
+
   public final native LineCharacter getCursor() /*-{
     return this.getCursor();
   }-*/;
@@ -209,6 +219,14 @@
     return FromTo.create(getCursor("start"), getCursor("end"));
   }
 
+  public final native void setSelection(LineCharacter anchor) /*-{
+    this.setSelection(anchor);
+  }-*/;
+
+  public final native void setSelection(LineCharacter anchor, LineCharacter head) /*-{
+    this.setSelection(anchor, head);
+  }-*/;
+
   public final native void setCursor(LineCharacter lineCh) /*-{
     this.setCursor(lineCh);
   }-*/;
@@ -341,4 +359,8 @@
     public void handle(CodeMirror instance, int line, String gutter,
         NativeEvent clickEvent);
   }
+
+  public interface BeforeSelectionChangeHandler {
+    public void handle(CodeMirror instance, LineCharacter anchor, LineCharacter head);
+  }
 }
diff --git a/gerrit-gwtui/src/main/java/net/codemirror/lib/Rect.java b/gerrit-gwtui/src/main/java/net/codemirror/lib/Rect.java
new file mode 100644
index 0000000..5691d9f
--- /dev/null
+++ b/gerrit-gwtui/src/main/java/net/codemirror/lib/Rect.java
@@ -0,0 +1,28 @@
+// Copyright (C) 2013 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 net.codemirror.lib;
+
+import com.google.gwt.core.client.JavaScriptObject;
+
+/** {left, right, top, bottom} objects used within CodeMirror. */
+public class Rect extends JavaScriptObject {
+  public final native double left() /*-{ return this.left }-*/;
+  public final native double right() /*-{ return this.right }-*/;
+  public final native double top() /*-{ return this.top }-*/;
+  public final native double bottom() /*-{ return this.bottom }-*/;
+
+  protected Rect() {
+  }
+}
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/change/GetRelated.java b/gerrit-server/src/main/java/com/google/gerrit/server/change/GetRelated.java
index d804f38..7ac872d 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/change/GetRelated.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/change/GetRelated.java
@@ -287,12 +287,15 @@
     CommitInfo commit;
     Integer _changeNumber;
     Integer _revisionNumber;
+    Integer _currentRevisionNumber;
 
     ChangeAndCommit(@Nullable Change change, @Nullable PatchSet ps, RevCommit c) {
       if (change != null) {
         changeId = change.getKey().get();
         _changeNumber = change.getChangeId();
         _revisionNumber = ps != null ? ps.getPatchSetId() : null;
+        PatchSet.Id curr = change.currentPatchSetId();
+        _currentRevisionNumber = curr != null ? curr.get() : null;
       }
 
       commit = new CommitInfo();
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 be4b0ce..b7b34b1 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
@@ -1710,6 +1710,7 @@
       if (newCommit == priorCommit) {
         // Ignore requests to make the change its current state.
         skip = true;
+        reject(inputCommand, "commit already exists");
         return false;
       }
 
diff --git a/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/CreateBranchCommand.java b/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/CreateBranchCommand.java
new file mode 100644
index 0000000..16ffe28
--- /dev/null
+++ b/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/CreateBranchCommand.java
@@ -0,0 +1,59 @@
+// Copyright (C) 2013 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.sshd.commands;
+
+import com.google.gerrit.extensions.api.GerritApi;
+import com.google.gerrit.extensions.api.projects.BranchApi;
+import com.google.gerrit.extensions.api.projects.BranchInput;
+import com.google.gerrit.extensions.restapi.RestApiException;
+import com.google.gerrit.server.project.CreateBranch;
+import com.google.gerrit.server.project.ProjectControl;
+import com.google.gerrit.sshd.CommandMetaData;
+import com.google.gerrit.sshd.SshCommand;
+import com.google.inject.Inject;
+
+import org.kohsuke.args4j.Argument;
+import org.kohsuke.args4j.Option;
+
+import java.io.IOException;
+
+/** Create a new branch. **/
+@CommandMetaData(name = "create-branch", description = "Create a new branch")
+final public class CreateBranchCommand extends SshCommand {
+
+  @Argument(index = 0, required = true, metaVar = "PROJECT", usage = "name of the project")
+  private ProjectControl project;
+
+  @Argument(index = 1, required = true, metaVar = "NAME", usage = "name of branch to be created")
+  private String name;
+
+  @Argument(index = 2, required = true, metaVar = "REVISION", usage = "base revision of the new branch")
+  private String revision;
+
+  @Inject
+  GerritApi gApi;
+
+  @Override
+  protected void run() throws UnloggedFailure {
+    try {
+      BranchInput in = new BranchInput();
+      in.revision = revision;
+      gApi.projects().name(project.getProject().getNameKey().get())
+          .branch(name).create(in);
+    } catch (RestApiException e) {
+      throw new UnloggedFailure(1, "fatal: " + e.getMessage(), e);
+    }
+  }
+}
diff --git a/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/MasterCommandModule.java b/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/MasterCommandModule.java
index a8d5c4d..a79e862 100644
--- a/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/MasterCommandModule.java
+++ b/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/MasterCommandModule.java
@@ -31,6 +31,7 @@
     command(gerrit, CreateGroupCommand.class);
     command(gerrit, RenameGroupCommand.class);
     command(gerrit, CreateProjectCommand.class);
+    command(gerrit, CreateBranchCommand.class);
     command(gerrit, AdminQueryShell.class);
     command(gerrit, SetReviewersCommand.class);
     command(gerrit, Receive.class);