Merge changes Ibf537436,I67b144eb into stable-2.15

* changes:
  Add account setting for defaulting new changes to WIP
  Add project setting for defaulting new changes to WIP
diff --git a/Documentation/config-project-config.txt b/Documentation/config-project-config.txt
index 3644845..b55980b 100644
--- a/Documentation/config-project-config.txt
+++ b/Documentation/config-project-config.txt
@@ -217,6 +217,19 @@
 Default is `INHERIT`, which means that this property is inherited from
 the parent project.
 
+[[change.workInProgressByDefault]]change.workInProgressByDefault::
++
+Controls whether all new changes in the project are set as WIP by default.
++
+Note that a new change will be ready if the `workInProgress` field in
+link:rest-api-changes.html#change-input[ChangeInput] is set to `false` explicitly
+when calling the link:rest-api-changes.html#create-change[CreateChange] REST API
+or the `ready` link:user-upload.html#wip[PushOption] is used during
+the Git push.
++
+Default is `INHERIT`, which means that this property is inherited from
+the parent project.
+
 [[submit-section]]
 === Submit section
 
diff --git a/Documentation/intro-user.txt b/Documentation/intro-user.txt
index 38af68e..8377555 100644
--- a/Documentation/intro-user.txt
+++ b/Documentation/intro-user.txt
@@ -827,6 +827,12 @@
 and download commands. Note that this option is only shown if the Flash plugin
 is available and the JavaScript Clipboard API is unavailable.
 
+- [[work-in-progress-by-default]]`Set new changes work-in-progress`:
++
+Whether new changes are uploaded as work-in-progress per default. This
+preference just sets the default; the behavior can still be overridden using a
+link:user-upload.html#wip[push option].
+
 [[my-menu]]
 In addition it is possible to customize the menu entries of the `My`
 menu. This can be used to make the navigation to frequently used
diff --git a/Documentation/rest-api-accounts.txt b/Documentation/rest-api-accounts.txt
index e7549d9..95dd4f2 100644
--- a/Documentation/rest-api-accounts.txt
+++ b/Documentation/rest-api-accounts.txt
@@ -1249,6 +1249,7 @@
     "review_category_strategy": "ABBREV",
     "mute_common_path_prefixes": true,
     "publish_comments_on_push": true,
+    "work_in_progress_by_default": true,
     "default_base_for_merges": "FIRST_PARENT",
     "my": [
       {
@@ -1355,6 +1356,7 @@
     "review_category_strategy": "NAME",
     "diff_view": "SIDE_BY_SIDE",
     "publish_comments_on_push": true,
+    "work_in_progress_by_default": true,
     "mute_common_path_prefixes": true,
     "my": [
       {
@@ -2645,6 +2647,9 @@
 |`publish_comments_on_push`     |not set if `false`|
 Whether to link:user-upload.html#publish-comments[publish draft comments] on
 push by default.
+|`work_in_progress_by_default`  |not set if `false`|
+Whether to link:user-upload.html#wip[set work-in-progress] on
+push or on create changes online by default.
 |============================================
 
 [[preferences-input]]
diff --git a/Documentation/rest-api-projects.txt b/Documentation/rest-api-projects.txt
index a85b8e6..4d03d88 100644
--- a/Documentation/rest-api-projects.txt
+++ b/Documentation/rest-api-projects.txt
@@ -2757,14 +2757,17 @@
 |`reject_implicit_merges`|optional|
 link:#inherited-boolean-info[InheritedBooleanInfo] that tells whether
 implicit merges should be rejected on changes pushed to the project.
-|`private_by_default`     ||
+|`private_by_default`         ||
 link:#inherited-boolean-info[InheritedBooleanInfo] that tells whether
 all new changes are set as private by default.
-|`max_object_size_limit`     ||
+|`work_in_progress_by_default`||
+link:#inherited-boolean-info[InheritedBooleanInfo] that tells whether
+all new changes are set as work-in-progress by default.
+|`max_object_size_limit`      ||
 The link:config-gerrit.html#receive.maxObjectSizeLimit[max object size
 limit] of this project as a link:#max-object-size-limit-info[
 MaxObjectSizeLimitInfo] entity.
-|`submit_type`               ||
+|`submit_type`                ||
 The default submit type of the project, can be `MERGE_IF_NECESSARY`,
 `FAST_FORWARD_ONLY`, `REBASE_IF_NECESSARY`, `REBASE_ALWAYS`, `MERGE_ALWAYS` or
 `CHERRY_PICK`.
diff --git a/Documentation/user-upload.txt b/Documentation/user-upload.txt
index da21809..1e76df5 100644
--- a/Documentation/user-upload.txt
+++ b/Documentation/user-upload.txt
@@ -309,6 +309,11 @@
 Only change owners, project owners and site administrators can specify
 `work-in-progress` and `ready` options on push.
 
+The default for this option can be set as a
+link:intro-user.html#work-in-progress-by-default[user preference]. If the
+preference is set so the default behavior is to create `work-in-progress`
+changes, this can be overridden with the `ready` option.
+
 [[message]]
 ==== Message
 
diff --git a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/api/change/ChangeIT.java b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/api/change/ChangeIT.java
index ebb66bb..991466b 100644
--- a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/api/change/ChangeIT.java
+++ b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/api/change/ChangeIT.java
@@ -432,6 +432,16 @@
   }
 
   @Test
+  public void createWipChangeWithWorkInProgressByDefaultForProject() throws Exception {
+    ConfigInput input = new ConfigInput();
+    input.workInProgressByDefault = InheritableBoolean.TRUE;
+    gApi.projects().name(project.get()).config(input);
+    String changeId =
+        gApi.changes().create(new ChangeInput(project.get(), "master", "Test Change")).get().id;
+    assertThat(gApi.changes().id(changeId).get().workInProgress).isTrue();
+  }
+
+  @Test
   public void setReadyForReviewNotAllowedWithoutPermission() throws Exception {
     PushOneCommit.Result rready = createChange();
     String changeId = rready.getChangeId();
diff --git a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/rest/change/WorkInProgressByDefaultIT.java b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/rest/change/WorkInProgressByDefaultIT.java
new file mode 100644
index 0000000..34d87d0
--- /dev/null
+++ b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/rest/change/WorkInProgressByDefaultIT.java
@@ -0,0 +1,158 @@
+// Copyright (C) 2018 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.rest.change;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import com.google.gerrit.acceptance.AbstractDaemonTest;
+import com.google.gerrit.acceptance.PushOneCommit;
+import com.google.gerrit.extensions.api.projects.ConfigInput;
+import com.google.gerrit.extensions.client.GeneralPreferencesInfo;
+import com.google.gerrit.extensions.client.InheritableBoolean;
+import com.google.gerrit.extensions.common.ChangeInfo;
+import com.google.gerrit.extensions.common.ChangeInput;
+import com.google.gerrit.reviewdb.client.Project;
+import org.eclipse.jgit.internal.storage.dfs.InMemoryRepository;
+import org.eclipse.jgit.junit.TestRepository;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+public class WorkInProgressByDefaultIT extends AbstractDaemonTest {
+  private Project.NameKey project1;
+  private Project.NameKey project2;
+
+  @Before
+  public void setUp() throws Exception {
+    project1 = createProject("project-1");
+    project2 = createProject("project-2", project1);
+  }
+
+  @After
+  public void tearDown() throws Exception {
+    setApiUser(admin);
+    GeneralPreferencesInfo prefs = gApi.accounts().id(admin.id.get()).getPreferences();
+    prefs.workInProgressByDefault = false;
+    gApi.accounts().id(admin.id.get()).setPreferences(prefs);
+  }
+
+  @Test
+  public void createChangeWithWorkInProgressByDefaultForProjectDisabled() throws Exception {
+    ChangeInfo info =
+        gApi.changes().create(new ChangeInput(project2.get(), "master", "empty change")).get();
+    assertThat(info.workInProgress).isNull();
+  }
+
+  @Test
+  public void createChangeWithWorkInProgressByDefaultForProjectEnabled() throws Exception {
+    setWorkInProgressByDefaultForProject(project2);
+    ChangeInput input = new ChangeInput(project2.get(), "master", "empty change");
+    assertThat(gApi.changes().create(input).get().workInProgress).isTrue();
+  }
+
+  @Test
+  public void createChangeWithWorkInProgressByDefaultForUserEnabled() throws Exception {
+    setWorkInProgressByDefaultForUser();
+    ChangeInput input = new ChangeInput(project2.get(), "master", "empty change");
+    assertThat(gApi.changes().create(input).get().workInProgress).isTrue();
+  }
+
+  @Test
+  public void createChangeBypassWorkInProgressByDefaultForProjectEnabled() throws Exception {
+    setWorkInProgressByDefaultForProject(project2);
+    ChangeInput input = new ChangeInput(project2.get(), "master", "empty change");
+    input.workInProgress = false;
+    assertThat(gApi.changes().create(input).get().workInProgress).isNull();
+  }
+
+  @Test
+  public void createChangeBypassWorkInProgressByDefaultForUserEnabled() throws Exception {
+    setWorkInProgressByDefaultForUser();
+    ChangeInput input = new ChangeInput(project2.get(), "master", "empty change");
+    input.workInProgress = false;
+    assertThat(gApi.changes().create(input).get().workInProgress).isNull();
+  }
+
+  @Test
+  public void createChangeWithWorkInProgressByDefaultForProjectInherited() throws Exception {
+    setWorkInProgressByDefaultForProject(project1);
+    ChangeInfo info =
+        gApi.changes().create(new ChangeInput(project2.get(), "master", "empty change")).get();
+    assertThat(info.workInProgress).isTrue();
+  }
+
+  @Test
+  public void pushWithWorkInProgressByDefaultForProjectEnabled() throws Exception {
+    setWorkInProgressByDefaultForProject(project2);
+    assertThat(createChange(project2).getChange().change().isWorkInProgress()).isTrue();
+  }
+
+  @Test
+  public void pushWithWorkInProgressByDefaultForUserEnabled() throws Exception {
+    setWorkInProgressByDefaultForUser();
+    assertThat(createChange(project2).getChange().change().isWorkInProgress()).isTrue();
+  }
+
+  @Test
+  public void pushBypassWorkInProgressByDefaultForProjectEnabled() throws Exception {
+    setWorkInProgressByDefaultForProject(project2);
+    assertThat(
+            createChange(project2, "refs/for/master%ready").getChange().change().isWorkInProgress())
+        .isFalse();
+  }
+
+  @Test
+  public void pushBypassWorkInProgressByDefaultForUserEnabled() throws Exception {
+    setWorkInProgressByDefaultForUser();
+    assertThat(
+            createChange(project2, "refs/for/master%ready").getChange().change().isWorkInProgress())
+        .isFalse();
+  }
+
+  @Test
+  public void pushWithWorkInProgressByDefaultForProjectDisabled() throws Exception {
+    assertThat(createChange(project2).getChange().change().isWorkInProgress()).isFalse();
+  }
+
+  @Test
+  public void pushWorkInProgressByDefaultForProjectInherited() throws Exception {
+    setWorkInProgressByDefaultForProject(project1);
+    assertThat(createChange(project2).getChange().change().isWorkInProgress()).isTrue();
+  }
+
+  private void setWorkInProgressByDefaultForProject(Project.NameKey p) throws Exception {
+    ConfigInput input = new ConfigInput();
+    input.workInProgressByDefault = InheritableBoolean.TRUE;
+    gApi.projects().name(p.get()).config(input);
+  }
+
+  private void setWorkInProgressByDefaultForUser() throws Exception {
+    GeneralPreferencesInfo prefs = gApi.accounts().id(admin.id.get()).getPreferences();
+    prefs.workInProgressByDefault = true;
+    gApi.accounts().id(admin.id.get()).setPreferences(prefs);
+  }
+
+  private PushOneCommit.Result createChange(Project.NameKey p) throws Exception {
+    return createChange(p, "refs/for/master");
+  }
+
+  private PushOneCommit.Result createChange(Project.NameKey p, String r) throws Exception {
+    TestRepository<InMemoryRepository> testRepo = cloneProject(p);
+    PushOneCommit push = pushFactory.create(db, admin.getIdent(), testRepo);
+    PushOneCommit.Result result = push.to(r);
+    result.assertOkStatus();
+    return result;
+  }
+}
diff --git a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/server/mail/ChangeNotificationsIT.java b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/server/mail/ChangeNotificationsIT.java
index 3ea8f8e..a94a63d 100644
--- a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/server/mail/ChangeNotificationsIT.java
+++ b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/server/mail/ChangeNotificationsIT.java
@@ -42,10 +42,14 @@
 import com.google.gerrit.extensions.api.changes.NotifyHandling;
 import com.google.gerrit.extensions.api.changes.ReviewInput;
 import com.google.gerrit.extensions.api.changes.SubmitInput;
+import com.google.gerrit.extensions.api.projects.ConfigInput;
+import com.google.gerrit.extensions.client.GeneralPreferencesInfo;
 import com.google.gerrit.extensions.client.GeneralPreferencesInfo.EmailStrategy;
+import com.google.gerrit.extensions.client.InheritableBoolean;
 import com.google.gerrit.extensions.client.ReviewerState;
 import com.google.gerrit.extensions.common.CommitInfo;
 import com.google.gerrit.extensions.common.CommitMessageInput;
+import com.google.gerrit.reviewdb.client.Project;
 import com.google.gerrit.server.change.PostReview;
 import com.google.gerrit.server.git.ProjectConfig;
 import com.google.gerrit.server.project.Util;
@@ -940,6 +944,38 @@
   }
 
   @Test
+  public void createWipChangeWithWorkInProgressByDefaultForProject() throws Exception {
+    setWorkInProgressByDefault(project, InheritableBoolean.TRUE);
+    StagedPreChange spc = stagePreChange("refs/for/master");
+    Truth.assertThat(gApi.changes().id(spc.changeId).get().workInProgress).isTrue();
+    assertThat(sender).notSent();
+  }
+
+  @Test
+  public void createWipChangeWithWorkInProgressByDefaultForUser() throws Exception {
+    // Make sure owner user is created
+    StagedChange sc = stageReviewableChange();
+    // All was cleaned already
+    assertThat(sender).notSent();
+
+    // Toggle workInProgress flag for owner
+    GeneralPreferencesInfo prefs = gApi.accounts().id(sc.owner.id.get()).getPreferences();
+    prefs.workInProgressByDefault = true;
+    gApi.accounts().id(sc.owner.id.get()).setPreferences(prefs);
+
+    // Create another change without notification that should be wip
+    StagedPreChange spc = stagePreChange("refs/for/master");
+    Truth.assertThat(gApi.changes().id(spc.changeId).get().workInProgress).isTrue();
+    assertThat(sender).notSent();
+
+    // Clean up workInProgressByDefault by owner
+    prefs = gApi.accounts().id(sc.owner.id.get()).getPreferences();
+    Truth.assertThat(prefs.workInProgressByDefault).isTrue();
+    prefs.workInProgressByDefault = false;
+    gApi.accounts().id(sc.owner.id.get()).setPreferences(prefs);
+  }
+
+  @Test
   public void createReviewableChangeWithNotifyOwnerReviewers() throws Exception {
     stagePreChange("refs/for/master%notify=OWNER_REVIEWERS");
     assertThat(sender).notSent();
@@ -2616,4 +2652,11 @@
     // PolyGerrit current immediately follows up with a review.
     gApi.changes().id(sc.changeId).revision("current").review(ReviewInput.noScore());
   }
+
+  private void setWorkInProgressByDefault(Project.NameKey p, InheritableBoolean v)
+      throws Exception {
+    ConfigInput input = new ConfigInput();
+    input.workInProgressByDefault = v;
+    gApi.projects().name(p.get()).config(input);
+  }
 }
diff --git a/gerrit-extension-api/src/main/java/com/google/gerrit/extensions/api/projects/ConfigInfo.java b/gerrit-extension-api/src/main/java/com/google/gerrit/extensions/api/projects/ConfigInfo.java
index 443e2064..6a9ad93 100644
--- a/gerrit-extension-api/src/main/java/com/google/gerrit/extensions/api/projects/ConfigInfo.java
+++ b/gerrit-extension-api/src/main/java/com/google/gerrit/extensions/api/projects/ConfigInfo.java
@@ -32,6 +32,7 @@
   public InheritedBooleanInfo requireSignedPush;
   public InheritedBooleanInfo rejectImplicitMerges;
   public InheritedBooleanInfo privateByDefault;
+  public InheritedBooleanInfo workInProgressByDefault;
   public InheritedBooleanInfo enableReviewerByEmail;
   public InheritedBooleanInfo matchAuthorToCommitterDate;
   public MaxObjectSizeLimitInfo maxObjectSizeLimit;
diff --git a/gerrit-extension-api/src/main/java/com/google/gerrit/extensions/api/projects/ConfigInput.java b/gerrit-extension-api/src/main/java/com/google/gerrit/extensions/api/projects/ConfigInput.java
index 0c1cec4..24c882c8 100644
--- a/gerrit-extension-api/src/main/java/com/google/gerrit/extensions/api/projects/ConfigInput.java
+++ b/gerrit-extension-api/src/main/java/com/google/gerrit/extensions/api/projects/ConfigInput.java
@@ -30,6 +30,7 @@
   public InheritableBoolean requireSignedPush;
   public InheritableBoolean rejectImplicitMerges;
   public InheritableBoolean privateByDefault;
+  public InheritableBoolean workInProgressByDefault;
   public InheritableBoolean enableReviewerByEmail;
   public InheritableBoolean matchAuthorToCommitterDate;
   public String maxObjectSizeLimit;
diff --git a/gerrit-extension-api/src/main/java/com/google/gerrit/extensions/client/GeneralPreferencesInfo.java b/gerrit-extension-api/src/main/java/com/google/gerrit/extensions/client/GeneralPreferencesInfo.java
index 9dcba5e..1f16d8d 100644
--- a/gerrit-extension-api/src/main/java/com/google/gerrit/extensions/client/GeneralPreferencesInfo.java
+++ b/gerrit-extension-api/src/main/java/com/google/gerrit/extensions/client/GeneralPreferencesInfo.java
@@ -158,6 +158,7 @@
   public EmailFormat emailFormat;
   public DefaultBase defaultBaseForMerges;
   public Boolean publishCommentsOnPush;
+  public Boolean workInProgressByDefault;
 
   public boolean isShowInfoInReviewCategory() {
     return getReviewCategoryStrategy() != ReviewCategoryStrategy.NONE;
@@ -227,6 +228,7 @@
     p.signedOffBy = false;
     p.defaultBaseForMerges = DefaultBase.FIRST_PARENT;
     p.publishCommentsOnPush = false;
+    p.workInProgressByDefault = false;
     return p;
   }
 }
diff --git a/gerrit-gwtui-common/src/main/java/com/google/gerrit/client/info/GeneralPreferences.java b/gerrit-gwtui-common/src/main/java/com/google/gerrit/client/info/GeneralPreferences.java
index 1dcb284..fbdf52c 100644
--- a/gerrit-gwtui-common/src/main/java/com/google/gerrit/client/info/GeneralPreferences.java
+++ b/gerrit-gwtui-common/src/main/java/com/google/gerrit/client/info/GeneralPreferences.java
@@ -151,6 +151,9 @@
   public final native boolean
       publishCommentsOnPush() /*-{ return this.publish_comments_on_push || false }-*/;
 
+  public final native boolean
+      workInProgressByDefault() /*-{ return this.work_in_progress_by_default || false }-*/;
+
   public final native JsArray<TopMenuItem> my() /*-{ return this.my; }-*/;
 
   public final native void changesPerPage(int n) /*-{ this.changes_per_page = n }-*/;
@@ -230,6 +233,9 @@
   public final native void publishCommentsOnPush(
       boolean p) /*-{ this.publish_comments_on_push = p }-*/;
 
+  public final native void workInProgressByDefault(
+      boolean p) /*-{ this.work_in_progress_by_default = p }-*/;
+
   public final void setMyMenus(List<TopMenuItem> myMenus) {
     initMy();
     for (TopMenuItem n : myMenus) {
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/account/AccountConstants.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/account/AccountConstants.java
index 0b32cd5..3e21619 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/account/AccountConstants.java
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/account/AccountConstants.java
@@ -69,6 +69,8 @@
 
   String publishCommentsOnPush();
 
+  String workInProgressByDefault();
+
   String myMenu();
 
   String myMenuInfo();
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/account/AccountConstants.properties b/gerrit-gwtui/src/main/java/com/google/gerrit/client/account/AccountConstants.properties
index deba4f8..59b8b3d 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/account/AccountConstants.properties
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/account/AccountConstants.properties
@@ -39,6 +39,7 @@
 muteCommonPathPrefixes = Mute Common Path Prefixes In File List
 signedOffBy = Insert Signed-off-by Footer For Inline Edit Changes
 publishCommentsOnPush = Publish Draft Comments When a Change Is Updated by Push
+workInProgressByDefault = Set all new changes work-in-progress by default
 myMenu = My Menu
 myMenuInfo = \
   Menu items for the 'My' top level menu. \
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/account/MyPreferencesScreen.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/account/MyPreferencesScreen.java
index f349065..afb8718 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/account/MyPreferencesScreen.java
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/account/MyPreferencesScreen.java
@@ -56,6 +56,7 @@
   private CheckBox muteCommonPathPrefixes;
   private CheckBox signedOffBy;
   private CheckBox publishCommentsOnPush;
+  private CheckBox workInProgressByDefault;
   private ListBox maximumPageSize;
   private ListBox dateFormat;
   private ListBox timeFormat;
@@ -163,9 +164,10 @@
     muteCommonPathPrefixes = new CheckBox(Util.C.muteCommonPathPrefixes());
     signedOffBy = new CheckBox(Util.C.signedOffBy());
     publishCommentsOnPush = new CheckBox(Util.C.publishCommentsOnPush());
+    workInProgressByDefault = new CheckBox(Util.C.workInProgressByDefault());
 
     boolean flashClippy = !UserAgent.hasJavaScriptClipboard() && UserAgent.Flash.isInstalled();
-    final Grid formGrid = new Grid(15 + (flashClippy ? 1 : 0), 2);
+    final Grid formGrid = new Grid(16 + (flashClippy ? 1 : 0), 2);
 
     int row = 0;
 
@@ -229,6 +231,10 @@
     formGrid.setWidget(row, fieldIdx, publishCommentsOnPush);
     row++;
 
+    formGrid.setText(row, labelIdx, "");
+    formGrid.setWidget(row, fieldIdx, workInProgressByDefault);
+    row++;
+
     if (flashClippy) {
       formGrid.setText(row, labelIdx, "");
       formGrid.setWidget(row, fieldIdx, useFlashClipboard);
@@ -264,6 +270,7 @@
     e.listenTo(muteCommonPathPrefixes);
     e.listenTo(signedOffBy);
     e.listenTo(publishCommentsOnPush);
+    e.listenTo(workInProgressByDefault);
     e.listenTo(diffView);
     e.listenTo(reviewCategoryStrategy);
     e.listenTo(emailStrategy);
@@ -303,6 +310,7 @@
     muteCommonPathPrefixes.setEnabled(on);
     signedOffBy.setEnabled(on);
     publishCommentsOnPush.setEnabled(on);
+    workInProgressByDefault.setEnabled(on);
     reviewCategoryStrategy.setEnabled(on);
     diffView.setEnabled(on);
     emailStrategy.setEnabled(on);
@@ -329,6 +337,7 @@
     muteCommonPathPrefixes.setValue(p.muteCommonPathPrefixes());
     signedOffBy.setValue(p.signedOffBy());
     publishCommentsOnPush.setValue(p.publishCommentsOnPush());
+    workInProgressByDefault.setValue(p.workInProgressByDefault());
     setListBox(
         reviewCategoryStrategy,
         GeneralPreferencesInfo.ReviewCategoryStrategy.NONE,
@@ -421,6 +430,7 @@
     p.muteCommonPathPrefixes(muteCommonPathPrefixes.getValue());
     p.signedOffBy(signedOffBy.getValue());
     p.publishCommentsOnPush(publishCommentsOnPush.getValue());
+    p.workInProgressByDefault(workInProgressByDefault.getValue());
     p.reviewCategoryStrategy(
         getListBox(
             reviewCategoryStrategy, ReviewCategoryStrategy.NONE, ReviewCategoryStrategy.values()));
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 b556519..9d33f5a 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
@@ -79,6 +79,8 @@
 
   String privateByDefault();
 
+  String workInProgressByDefault();
+
   String enableReviewerByEmail();
 
   String matchAuthorToCommitterDate();
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 62f3778..eca5dc1 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
@@ -31,6 +31,7 @@
 requireChangeID = Require <code>Change-Id</code> in commit message
 rejectImplicitMerges = Reject implicit merges when changes are pushed for review
 privateByDefault = Set all new changes private by default
+workInProgressByDefault = Set all new changes work-in-progress by default
 headingMaxObjectSizeLimit = Maximum Git object size limit
 headingGroupOptions = Group Options
 isVisibleToAll = Make group visible to all registered users.
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/admin/ProjectInfoScreen.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/admin/ProjectInfoScreen.java
index 4e94250..d4faa90 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/admin/ProjectInfoScreen.java
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/admin/ProjectInfoScreen.java
@@ -87,6 +87,7 @@
   private ListBox requireSignedPush;
   private ListBox rejectImplicitMerges;
   private ListBox privateByDefault;
+  private ListBox workInProgressByDefault;
   private ListBox enableReviewerByEmail;
   private ListBox matchAuthorToCommitterDate;
   private NpTextBox maxObjectSizeLimit;
@@ -197,6 +198,7 @@
     requireChangeID.setEnabled(isOwner);
     rejectImplicitMerges.setEnabled(isOwner);
     privateByDefault.setEnabled(isOwner);
+    workInProgressByDefault.setEnabled(isOwner);
     maxObjectSizeLimit.setEnabled(isOwner);
     enableReviewerByEmail.setEnabled(isOwner);
     matchAuthorToCommitterDate.setEnabled(isOwner);
@@ -277,6 +279,10 @@
     saveEnabler.listenTo(privateByDefault);
     grid.addHtml(AdminConstants.I.privateByDefault(), privateByDefault);
 
+    workInProgressByDefault = newInheritedBooleanBox();
+    saveEnabler.listenTo(workInProgressByDefault);
+    grid.addHtml(AdminConstants.I.workInProgressByDefault(), workInProgressByDefault);
+
     enableReviewerByEmail = newInheritedBooleanBox();
     saveEnabler.listenTo(enableReviewerByEmail);
     grid.addHtml(AdminConstants.I.enableReviewerByEmail(), enableReviewerByEmail);
@@ -417,6 +423,7 @@
     }
     setBool(rejectImplicitMerges, result.rejectImplicitMerges());
     setBool(privateByDefault, result.privateByDefault());
+    setBool(workInProgressByDefault, result.workInProgressByDefault());
     setBool(enableReviewerByEmail, result.enableReviewerByEmail());
     setBool(matchAuthorToCommitterDate, result.matchAuthorToCommitterDate());
     setSubmitType(result.submitType());
@@ -690,6 +697,7 @@
         rsp,
         getBool(rejectImplicitMerges),
         getBool(privateByDefault),
+        getBool(workInProgressByDefault),
         getBool(enableReviewerByEmail),
         getBool(matchAuthorToCommitterDate),
         maxObjectSizeLimit.getText().trim(),
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/projects/ConfigInfo.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/projects/ConfigInfo.java
index b8effdf..98dcbb6 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/projects/ConfigInfo.java
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/projects/ConfigInfo.java
@@ -60,6 +60,9 @@
   public final native InheritedBooleanInfo privateByDefault()
       /*-{ return this.private_by_default; }-*/ ;
 
+  public final native InheritedBooleanInfo workInProgressByDefault()
+      /*-{ return this.work_in_progress_by_default; }-*/ ;
+
   public final native InheritedBooleanInfo enableReviewerByEmail()
       /*-{ return this.enable_reviewer_by_email; }-*/ ;
 
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/projects/ProjectApi.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/projects/ProjectApi.java
index 3766dd9..7a4ec83 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/projects/ProjectApi.java
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/projects/ProjectApi.java
@@ -153,6 +153,7 @@
       InheritableBoolean requireSignedPush,
       InheritableBoolean rejectImplicitMerges,
       InheritableBoolean privateByDefault,
+      InheritableBoolean workInProgressByDefault,
       InheritableBoolean enableReviewerByEmail,
       InheritableBoolean matchAuthorToCommitterDate,
       String maxObjectSizeLimit,
@@ -175,6 +176,7 @@
     }
     in.setRejectImplicitMerges(rejectImplicitMerges);
     in.setPrivateByDefault(privateByDefault);
+    in.setWorkInProgressByDefault(workInProgressByDefault);
     in.setMaxObjectSizeLimit(maxObjectSizeLimit);
     in.setSubmitType(submitType);
     in.setState(state);
@@ -311,6 +313,13 @@
 
     private native void setPrivateByDefault(String v) /*-{ if(v)this.private_by_default=v; }-*/;
 
+    final void setWorkInProgressByDefault(InheritableBoolean v) {
+      setWorkInProgressByDefault(v.name());
+    }
+
+    private native void setWorkInProgressByDefault(
+        String v) /*-{ if(v)this.work_in_progress_by_default=v; }-*/;
+
     final void setEnableReviewerByEmail(InheritableBoolean v) {
       setEnableReviewerByEmailRaw(v.name());
     }
diff --git a/gerrit-reviewdb/src/main/java/com/google/gerrit/reviewdb/client/Project.java b/gerrit-reviewdb/src/main/java/com/google/gerrit/reviewdb/client/Project.java
index e756ce5..b98359f 100644
--- a/gerrit-reviewdb/src/main/java/com/google/gerrit/reviewdb/client/Project.java
+++ b/gerrit-reviewdb/src/main/java/com/google/gerrit/reviewdb/client/Project.java
@@ -103,6 +103,7 @@
 
   protected InheritableBoolean rejectImplicitMerges;
   protected InheritableBoolean privateByDefault;
+  protected InheritableBoolean workInProgressByDefault;
 
   protected InheritableBoolean enableReviewerByEmail;
 
@@ -122,6 +123,7 @@
     enableSignedPush = InheritableBoolean.INHERIT;
     requireSignedPush = InheritableBoolean.INHERIT;
     privateByDefault = InheritableBoolean.INHERIT;
+    workInProgressByDefault = InheritableBoolean.INHERIT;
     enableReviewerByEmail = InheritableBoolean.INHERIT;
     matchAuthorToCommitterDate = InheritableBoolean.INHERIT;
   }
@@ -174,6 +176,14 @@
     this.privateByDefault = privateByDefault;
   }
 
+  public InheritableBoolean getWorkInProgressByDefault() {
+    return workInProgressByDefault;
+  }
+
+  public void setWorkInProgressByDefault(InheritableBoolean workInProgressByDefault) {
+    this.workInProgressByDefault = workInProgressByDefault;
+  }
+
   public InheritableBoolean getEnableReviewerByEmail() {
     return enableReviewerByEmail;
   }
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/change/CreateChange.java b/gerrit-server/src/main/java/com/google/gerrit/server/change/CreateChange.java
index c6e08ff..bbc3de0 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/change/CreateChange.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/change/CreateChange.java
@@ -238,6 +238,12 @@
       AccountState account = accountCache.get(me.getAccountId());
       GeneralPreferencesInfo info = account.getAccount().getGeneralPreferencesInfo();
 
+      boolean isWorkInProgress =
+          input.workInProgress == null
+              ? rsrc.getProjectState().isWorkInProgressByDefault()
+                  || MoreObjects.firstNonNull(info.workInProgressByDefault, false)
+              : input.workInProgress;
+
       // Add a Change-Id line if there isn't already one
       String commitMessage = subject;
       if (ChangeIdUtil.indexOfChangeId(commitMessage, "\n") == -1) {
@@ -280,7 +286,7 @@
       }
       ins.setTopic(topic);
       ins.setPrivate(isPrivate);
-      ins.setWorkInProgress(input.workInProgress != null && input.workInProgress);
+      ins.setWorkInProgress(isWorkInProgress);
       ins.setGroups(groups);
       ins.setNotify(input.notify);
       ins.setAccountsToNotify(notifyUtil.resolveAccounts(input.notifyDetails));
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/git/ProjectConfig.java b/gerrit-server/src/main/java/com/google/gerrit/server/git/ProjectConfig.java
index 3c74f86..40b3a1f 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/git/ProjectConfig.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/git/ProjectConfig.java
@@ -127,6 +127,7 @@
 
   private static final String CHANGE = "change";
   private static final String KEY_PRIVATE_BY_DEFAULT = "privateByDefault";
+  private static final String KEY_WORK_IN_PROGRESS_BY_DEFAULT = "workInProgressByDefault";
 
   private static final String SUBMIT = "submit";
   private static final String KEY_ACTION = "action";
@@ -539,6 +540,9 @@
     p.setPrivateByDefault(
         getEnum(rc, CHANGE, null, KEY_PRIVATE_BY_DEFAULT, InheritableBoolean.INHERIT));
 
+    p.setWorkInProgressByDefault(
+        getEnum(rc, CHANGE, null, KEY_WORK_IN_PROGRESS_BY_DEFAULT, InheritableBoolean.INHERIT));
+
     p.setEnableReviewerByEmail(
         getEnum(rc, REVIEWER, null, KEY_ENABLE_REVIEWER_BY_EMAIL, InheritableBoolean.INHERIT));
 
@@ -1122,6 +1126,14 @@
 
     set(
         rc,
+        CHANGE,
+        null,
+        KEY_WORK_IN_PROGRESS_BY_DEFAULT,
+        p.getWorkInProgressByDefault(),
+        InheritableBoolean.INHERIT);
+
+    set(
+        rc,
         REVIEWER,
         null,
         KEY_ENABLE_REVIEWER_BY_EMAIL,
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/git/receive/ReceiveCommits.java b/gerrit-server/src/main/java/com/google/gerrit/server/git/receive/ReceiveCommits.java
index 085f94d..c4a3620 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/git/receive/ReceiveCommits.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/git/receive/ReceiveCommits.java
@@ -2127,6 +2127,7 @@
     }
 
     private void setChangeId(int id) {
+      possiblyOverrideWorkInProgress();
 
       changeId = new Change.Id(id);
       ins =
@@ -2147,6 +2148,17 @@
       }
     }
 
+    private void possiblyOverrideWorkInProgress() {
+      // When wip or ready explicitly provided, leave it as is.
+      if (magicBranch.workInProgress || magicBranch.ready) {
+        return;
+      }
+      magicBranch.workInProgress =
+          projectCache.get(project.getNameKey()).isWorkInProgressByDefault()
+              || firstNonNull(
+                  user.getAccount().getGeneralPreferencesInfo().workInProgressByDefault, false);
+    }
+
     private void addOps(BatchUpdate bu) throws RestApiException {
       checkState(changeId != null, "must call setChangeId before addOps");
       try {
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/project/ConfigInfoImpl.java b/gerrit-server/src/main/java/com/google/gerrit/server/project/ConfigInfoImpl.java
index eb0dde4..ed3754e 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/project/ConfigInfoImpl.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/project/ConfigInfoImpl.java
@@ -59,6 +59,7 @@
     InheritedBooleanInfo requireSignedPush = new InheritedBooleanInfo();
     InheritedBooleanInfo rejectImplicitMerges = new InheritedBooleanInfo();
     InheritedBooleanInfo privateByDefault = new InheritedBooleanInfo();
+    InheritedBooleanInfo workInProgressByDefault = new InheritedBooleanInfo();
     InheritedBooleanInfo enableReviewerByEmail = new InheritedBooleanInfo();
     InheritedBooleanInfo matchAuthorToCommitterDate = new InheritedBooleanInfo();
 
@@ -77,6 +78,7 @@
     requireSignedPush.configuredValue = p.getRequireSignedPush();
     rejectImplicitMerges.configuredValue = p.getRejectImplicitMerges();
     privateByDefault.configuredValue = p.getPrivateByDefault();
+    workInProgressByDefault.configuredValue = p.getWorkInProgressByDefault();
     enableReviewerByEmail.configuredValue = p.getEnableReviewerByEmail();
     matchAuthorToCommitterDate.configuredValue = p.getMatchAuthorToCommitterDate();
 
@@ -91,6 +93,7 @@
       enableSignedPush.inheritedValue = projectState.isEnableSignedPush();
       requireSignedPush.inheritedValue = projectState.isRequireSignedPush();
       privateByDefault.inheritedValue = projectState.isPrivateByDefault();
+      workInProgressByDefault.inheritedValue = projectState.isWorkInProgressByDefault();
       rejectImplicitMerges.inheritedValue = projectState.isRejectImplicitMerges();
       enableReviewerByEmail.inheritedValue = projectState.isEnableReviewerByEmail();
       matchAuthorToCommitterDate.inheritedValue = projectState.isMatchAuthorToCommitterDate();
@@ -109,6 +112,7 @@
       this.requireSignedPush = requireSignedPush;
     }
     this.privateByDefault = privateByDefault;
+    this.workInProgressByDefault = workInProgressByDefault;
 
     MaxObjectSizeLimitInfo maxObjectSizeLimit = new MaxObjectSizeLimitInfo();
     maxObjectSizeLimit.value =
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/project/ProjectState.java b/gerrit-server/src/main/java/com/google/gerrit/server/project/ProjectState.java
index 3015164..2813df1 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/project/ProjectState.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/project/ProjectState.java
@@ -411,6 +411,10 @@
     return getInheritableBoolean(Project::getPrivateByDefault);
   }
 
+  public boolean isWorkInProgressByDefault() {
+    return getInheritableBoolean(Project::getWorkInProgressByDefault);
+  }
+
   public boolean isEnableReviewerByEmail() {
     return getInheritableBoolean(Project::getEnableReviewerByEmail);
   }
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/project/PutConfig.java b/gerrit-server/src/main/java/com/google/gerrit/server/project/PutConfig.java
index 75d9b5d..d6b5d567 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/project/PutConfig.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/project/PutConfig.java
@@ -151,6 +151,10 @@
         p.setPrivateByDefault(input.privateByDefault);
       }
 
+      if (input.workInProgressByDefault != null) {
+        p.setWorkInProgressByDefault(input.workInProgressByDefault);
+      }
+
       if (input.maxObjectSizeLimit != null) {
         p.setMaxObjectSizeLimit(input.maxObjectSizeLimit);
       }
diff --git a/polygerrit-ui/app/elements/admin/gr-create-change-dialog/gr-create-change-dialog.html b/polygerrit-ui/app/elements/admin/gr-create-change-dialog/gr-create-change-dialog.html
index 914f9e2..8352a47 100644
--- a/polygerrit-ui/app/elements/admin/gr-create-change-dialog/gr-create-change-dialog.html
+++ b/polygerrit-ui/app/elements/admin/gr-create-change-dialog/gr-create-change-dialog.html
@@ -96,7 +96,8 @@
             <label for="wipChangeCheckBox">WIP Change</label>
             <input
                 type="checkbox"
-                id="wipChangeCheckBox">
+                id="wipChangeCheckBox"
+                checked$="[[_projectConfig.work_in_progress_by_default.inherited_value]]">
           </section>
         </section>
       </div>
diff --git a/polygerrit-ui/app/elements/admin/gr-create-change-dialog/gr-create-change-dialog_test.html b/polygerrit-ui/app/elements/admin/gr-create-change-dialog/gr-create-change-dialog_test.html
index 4f5dd46..85d7f7e 100644
--- a/polygerrit-ui/app/elements/admin/gr-create-change-dialog/gr-create-change-dialog_test.html
+++ b/polygerrit-ui/app/elements/admin/gr-create-change-dialog/gr-create-change-dialog_test.html
@@ -58,6 +58,7 @@
       element.projectName = 'test-project';
       element._projectConfig = {
         private_by_default: {},
+        work_in_progress_by_default: {},
       };
     });
 
@@ -100,6 +101,41 @@
       });
     });
 
+    test('new change created with wip by default', () => {
+      element._projectConfig = {
+        work_in_progress_by_default: {
+          inherited_value: true,
+        },
+      };
+
+      const configInputObj = {
+        branch: 'test-branch',
+        topic: 'test-topic',
+        subject: 'first change created with polygerrit ui',
+        project: element.projectName,
+        work_in_progress: true,
+      };
+
+      const saveStub = sandbox.stub(element.$.restAPI,
+          'createChange', () => {
+            return Promise.resolve({});
+          });
+
+      element.project = element.projectName;
+      element.branch = 'test-branch';
+      element.topic = 'test-topic';
+      element.subject = 'first change created with polygerrit ui';
+      assert.isTrue(element.$.wipChangeCheckBox.checked);
+
+      element.$.branchInput.bindValue = configInputObj.branch;
+      element.$.tagNameInput.bindValue = configInputObj.topic;
+      element.$.messageInput.bindValue = configInputObj.subject;
+
+      element.handleCreateChange().then(() => {
+        assert.isTrue(saveStub.lastCall.calledWithExactly(configInputObj));
+      });
+    });
+
     test('new change created with wip', () => {
       const configInputObj = {
         branch: 'test-branch',
diff --git a/polygerrit-ui/app/elements/admin/gr-project/gr-project.html b/polygerrit-ui/app/elements/admin/gr-project/gr-project.html
index 8ba27d9..0a19a08 100644
--- a/polygerrit-ui/app/elements/admin/gr-project/gr-project.html
+++ b/polygerrit-ui/app/elements/admin/gr-project/gr-project.html
@@ -240,6 +240,22 @@
                 </span>
               </section>
               <section>
+                <span class="title">
+                  Set new changes to "work in progress" by default</span>
+                <span class="value">
+                  <gr-select
+                      id="setAllNewChangesWorkInProgressByDefaultSelect"
+                      bind-value="{{_projectConfig.work_in_progress_by_default.configured_value}}">
+                    <select disabled$="[[_readOnly]]">
+                      <template is="dom-repeat"
+                          items="[[_formatBooleanSelect(_projectConfig.work_in_progress_by_default)]]">
+                        <option value="[[item.value]]">[[item.label]]</option>
+                      </template>
+                    </select>
+                  </gr-select>
+                </span>
+              </section>
+              <section>
                 <span class="title">Maximum Git object size limit</span>
                 <span class="value">
                   <input
diff --git a/polygerrit-ui/app/elements/admin/gr-project/gr-project_test.html b/polygerrit-ui/app/elements/admin/gr-project/gr-project_test.html
index 8013852..0840076 100644
--- a/polygerrit-ui/app/elements/admin/gr-project/gr-project_test.html
+++ b/polygerrit-ui/app/elements/admin/gr-project/gr-project_test.html
@@ -89,6 +89,10 @@
               value: false,
               configured_value: 'FALSE',
             },
+            work_in_progress_by_default: {
+              value: false,
+              configured_value: 'FALSE',
+            },
             match_author_to_committer_date: {
               value: false,
               configured_value: 'FALSE',
@@ -260,6 +264,7 @@
           require_signed_push: 'TRUE',
           reject_implicit_merges: 'TRUE',
           private_by_default: 'TRUE',
+          work_in_progress_by_default: 'TRUE',
           match_author_to_committer_date: 'TRUE',
           max_object_size_limit: 10,
           submit_type: 'FAST_FORWARD_ONLY',
@@ -294,6 +299,8 @@
               configInputObj.reject_implicit_merges;
           element.$.setAllnewChangesPrivateByDefaultSelect.bindValue =
               configInputObj.private_by_default;
+          element.$.setAllNewChangesWorkInProgressByDefaultSelect.bindValue =
+              configInputObj.work_in_progress_by_default;
           element.$.matchAuthoredDateWithCommitterDateSelect.bindValue =
               configInputObj.match_author_to_committer_date;
           element.$.maxGitObjSizeInput.bindValue =
diff --git a/polygerrit-ui/app/elements/settings/gr-settings-view/gr-settings-view.html b/polygerrit-ui/app/elements/settings/gr-settings-view/gr-settings-view.html
index addb9da..49ba141 100644
--- a/polygerrit-ui/app/elements/settings/gr-settings-view/gr-settings-view.html
+++ b/polygerrit-ui/app/elements/settings/gr-settings-view/gr-settings-view.html
@@ -191,6 +191,16 @@
             </span>
           </section>
           <section>
+            <span class="title">Set new changes to "work in progress" by default</span>
+            <span class="value">
+              <input
+                  id="workInProgressByDefault"
+                  type="checkbox"
+                  checked$="[[_localPrefs.work_in_progress_by_default]]"
+                  on-change="_handleWorkInProgressByDefault">
+            </span>
+          </section>
+          <section>
             <span class="title">
               Insert Signed-off-by Footer For Inline Edit Changes
             </span>
diff --git a/polygerrit-ui/app/elements/settings/gr-settings-view/gr-settings-view.js b/polygerrit-ui/app/elements/settings/gr-settings-view/gr-settings-view.js
index 115a612..3b0f509 100644
--- a/polygerrit-ui/app/elements/settings/gr-settings-view/gr-settings-view.js
+++ b/polygerrit-ui/app/elements/settings/gr-settings-view/gr-settings-view.js
@@ -22,6 +22,7 @@
     'diff_view',
     'expand_inline_diffs',
     'publish_comments_on_push',
+    'work_in_progress_by_default',
     'signed_off_by',
     'email_format',
   ];
@@ -265,6 +266,11 @@
           this.$.publishCommentsOnPush.checked);
     },
 
+    _handleWorkInProgressByDefault() {
+      this.set('_localPrefs.work_in_progress_by_default',
+          this.$.workInProgressByDefault.checked);
+    },
+
     _handleInsertSignedOff() {
       this.set('_localPrefs.signed_off_by', this.$.insertSignedOff.checked);
     },
diff --git a/polygerrit-ui/app/elements/settings/gr-settings-view/gr-settings-view_test.html b/polygerrit-ui/app/elements/settings/gr-settings-view/gr-settings-view_test.html
index 6b998bf..01a3dc2 100644
--- a/polygerrit-ui/app/elements/settings/gr-settings-view/gr-settings-view_test.html
+++ b/polygerrit-ui/app/elements/settings/gr-settings-view/gr-settings-view_test.html
@@ -173,6 +173,9 @@
       assert.equal(valueOf('Publish comments on push', 'preferences')
           .firstElementChild.checked, false);
       assert.equal(valueOf(
+          'Set new changes to "work in progress" by default', 'preferences')
+          .firstElementChild.checked, false);
+      assert.equal(valueOf(
           'Insert Signed-off-by Footer For Inline Edit Changes', 'preferences')
           .firstElementChild.checked, false);
 
@@ -232,6 +235,30 @@
       });
     });
 
+    test('set new changes work-in-progress', done => {
+      const newChangesWorkInProgress =
+        valueOf('Set new changes to "work in progress" by default',
+            'preferences').firstElementChild;
+      MockInteractions.tap(newChangesWorkInProgress);
+
+      assert.isFalse(element._menuChanged);
+      assert.isTrue(element._prefsChanged);
+
+      stub('gr-rest-api-interface', {
+        savePreferences(prefs) {
+          assert.equal(prefs.work_in_progress_by_default, true);
+          return Promise.resolve();
+        },
+      });
+
+      // Save the change.
+      element._handleSavePreferences().then(() => {
+        assert.isFalse(element._prefsChanged);
+        assert.isFalse(element._menuChanged);
+        done();
+      });
+    });
+
     test('diff preferences', done => {
       // Rendered with the expected preferences selected.
       assert.equal(valueOf('Context', 'diffPreferences')