diff --git a/src/applications/differential/field/specification/revisionstatus/DifferentialRevisionStatusFieldSpecification.php b/src/applications/differential/field/specification/revisionstatus/DifferentialRevisionStatusFieldSpecification.php
index 4fb35648ea..09c444490f 100644
--- a/src/applications/differential/field/specification/revisionstatus/DifferentialRevisionStatusFieldSpecification.php
+++ b/src/applications/differential/field/specification/revisionstatus/DifferentialRevisionStatusFieldSpecification.php
@@ -36,10 +36,10 @@ final class DifferentialRevisionStatusFieldSpecification
if ($status == ArcanistDifferentialRevisionStatus::ACCEPTED) {
switch ($diff->getSourceControlSystem()) {
case PhabricatorRepositoryType::REPOSITORY_TYPE_MERCURIAL:
- $next_step = 'arc merge';
+ $next_step = 'hg push';
break;
case PhabricatorRepositoryType::REPOSITORY_TYPE_GIT:
- $next_step = 'arc amend or arc merge';
+ $next_step = 'arc land';
break;
case PhabricatorRepositoryType::REPOSITORY_TYPE_SVN:
$next_step = 'arc commit';
diff --git a/src/docs/userguide/arcanist.diviner b/src/docs/userguide/arcanist.diviner
index a73c6440b3..59463bb715 100644
--- a/src/docs/userguide/arcanist.diviner
+++ b/src/docs/userguide/arcanist.diviner
@@ -122,164 +122,9 @@ to your ##.bashrc##, ##.profile## or similar:
source /path/to/arcanist/resources/shell/bash-completion
-= Running Arcanist =
+== Next Steps ==
-Arcanist is a context-sensitive command which you should run in a working copy,
-like ##git##, ##hg##, or ##svn##. Generally speaking, ##arc## commands operate
-on changed files in the working copy in SVN, a commit range you specify in git,
-and outgoing changes on the current branch in Mercurial.
+Continue by:
-== SVN Basics ==
-
-To **create a revision** in SVN:
-
- $ nano source_code.c # Make changes.
- $ arc diff
-
-This will give you a diff URI, which you can use to create a new revision via
-the web UI. To later **update an existing revision**, just do the same thing:
-
- $ nano source_code.c # Make more changes.
- $ arc diff
-
-This time, attach the diff to your existing revision. Once your revision has
-been accepted, you can commit it like this:
-
- $ arc commit
-
-== Git Basics ==
-
-There are a lot of ways to use git, and Arcanist is flexible enough to handle
-several of them. Git workflows divide into two major groups based on your
-**doctrine of history mutability**.
-
-Choose a **history mutability doctrine** by setting ##"immutable_history"## in
-your ##.arcconfig##. Valid values are ##true## to enforce a **conservative
-history mutability doctrine** or ##false## to enforce a **liberal history
-mutability doctrine**.
-
-A **liberal history mutability doctrine** means you rewrite local history. You
-develop in feature branches, but squash or amend before pushing by using ##git
-commit --amend## or ##git rebase -i##. Generally, one idea in the remote is
-represented by one commit. Arc will read revision information from commit
-messages, and you will finalize commits with ##arc amend##.
-
-A **conservative history mutability doctrine** means that you do not rewrite
-local history. This is similar to how Mercurial works. You develop in feature
-branches and push them without squashing commits. You do not use ##git commit
---amend## or ##git rebase -i##. Generally, one idea in the remote is represented
-by many commits. You will specify revision information via web workflows, and
-finalize commits with ##arc merge##.
-
-You can also choose no doctrine, which allows you to use both ##arc amend##
-and ##arc merge##. This isn't recommended, but Phabricator explicitly tries to
-support a broad range of git workflows. For recommendations on how to use git
-and why this choice of doctrines exists, see @{article:Recommendations on
-Revision Control}. If you aren't compelled by this and want to use a mixed
-workflow, you can pick and choose parts of each workflow.
-
-Phabricator associates commits to revisions (code reviews) by using commit
-messages and commit hashes. It will be unable to detect that you have committed
-a revision if you rebase (which changes all the hashes), and don't ##arc amend##
-or ##arc merge##, and don't ##arc diff## to update Differential with the new
-local hashes. You can use ##arc mark-committed## to explicitly mark revisions
-committed.
-
-=== Git: Conservative Mutability Doctrine ===
-
-NOTE: This doctrine is new and experimental.
-
-This section assumes you are using git with a **conservative history mutability
-doctrine** and have set ##"immutable_history" : true## in your ##.arcconfig##.
-
-To **create or update a revision** in git with a conservative doctrine:
-
- $ git checkout master
- $ git checkout -b feature # Create a feature branch
- $ git commit -m '...' # Make a commit
- $ arc diff master # Send changes since master for review
- $ git commit -m '...' # Make more changes
- $ git commit -m '...'
- $ arc diff master # Update the revision
-
-Once the revision has been accepted:
-
- $ git checkout master # Checkout master
- $ arc merge feature # Merge your feature branch with "arc merge" to
- # generate a rich merge commit.
-
-Now you can ##git push## or similar.
-
-=== Git: Liberal Mutability Doctrine ===
-
-This section assumes you are using git with a **liberal history mutability
-doctrine** and have set ##"immutable_history" : false## in your ##.arcconfig##.
-
-Under a liberal mutability doctrine, arc will read revision information from
-your commit message. Use a commit template similar to this one:
-
- arcanist/resources/git/commit-template.txt
-
-The easiest way to set up the template is to check it into your repository
-somewhere and then add this to your ##.git/config## file:
-
- [commit]
- template = path/to/template.txt
-
-You can also configure it globally, consult the git documentation for details.
-
-To **create a revision** in git:
-
- $ nano source_code.c # Make changes.
- $ git commit -a # Fill out the template.
- $ arc diff origin/master # Send changes from the origin for review.
-
-To **update a revision** in git by amending HEAD:
-
- $ nano source_code.c # Make changes.
- $ git commit -a --amend # Amend into HEAD.
- $ arc diff origin/master # Send changes from the origin for review.
-
-To **update a revision** in git by stacking local commits:
-
- $ nano source_code.c # Make changes.
- $ git commit -a -m '...' # Make another local commit.
- $ arc diff origin/master # Send changes from the origin for review.
-
-To **create and update a revision** using feature branches:
-
- $ git checkout master
- $ git checkout -b feature # Create a branch.
- $ nano source_code.c # Make changes.
- $ git commit -a # Fill out the template.
- $ arc diff master # Diff changes between here and branch 'master'
- $ nano source_code.c # Make more changes.
- $ git commit -a -m '...' # Or you can amend.
- $ arc diff master # Updates the diff.
-
-Once your revision has been accepted, use ##arc amend## to finalize it.
-
- $ git rebase -i # Squash commits if necessary.
- $ arc amend # Update HEAD with final revision information.
-
-After amending, you can push the commit to the remote with ##git push## or
-##git svn dcommit## or via whatever other channel your project uses as
-applicable.
-
-== Mercurial ==
-
-Mercurial works similarly to git's immutable history doctrine.
-
-To **create or update** a revision in Mercurial:
-
- $ hg commit -m '...' # Create a commit
- $ arc diff # Creates or updates a revision with outgoing changes
- # on this branch.
-
-Once a revision has been accepted, you can finalize it with ##arc merge##:
-
- $ arc merge # Works like "hg merge && hg commit" but gives you a
- # rich commit message.
-
-This won't work if there are no remote changes on your branch, since the merge
-is linear. In this case, just skip this step. You can now "hg push" or similar.
+ - learning how to use `arc` to send changes for review with
+ {@article:Arcanist User Guide: arc diff}.
diff --git a/src/docs/userguide/arcanist_diff.diviner b/src/docs/userguide/arcanist_diff.diviner
new file mode 100644
index 0000000000..26bd83f773
--- /dev/null
+++ b/src/docs/userguide/arcanist_diff.diviner
@@ -0,0 +1,154 @@
+@title Arcanist User Guide: arc diff
+@group userguide
+
+Guide to running `arc diff`.
+
+= Overview =
+
+This article assumes you have `arc` installed and running; if not, see
+@{article:Arcanist User Guide} for help getting it set up.
+
+This document is intended for users of `arc diff`, and is a practical
+guide to using it to send changes for review. If you are installing and
+configuring Phabricator, make sure to read the more comprehensive information in
+@{article:Arcanist User Guide: Configuring a New Project}.
+
+While `arc` has a large number of commands that interface with various
+Phabricator applications, the primary use of `arc` is to send changes for
+review in Differential (for more information on Differential, see
+@{article:Differential User Guide}). If you aren't familiar with Differential,
+it may be instructive to read that article first to understand the big picture
+of how the code review workflow works.
+
+You send changes for review by running `arc diff`. The rest of this document
+explains how to use `arc diff`, and how the entire review workflow operates for
+different version control systems.
+
+= Subversion =
+
+In Subversion, `arc diff` sends the **uncommitted changes in the working copy**
+for review.
+
+To **create a revision** in SVN:
+
+ $ nano source_code.c # Make changes.
+ $ arc diff
+
+This will prompt you for information about the revision. To later **update an
+existing revision**, just do the same thing:
+
+ $ nano source_code.c # Make more changes.
+ $ arc diff
+
+This time, `arc` will prompt you to update the revision. Once your revision has
+been accepted, you can commit it like this:
+
+ $ arc commit
+
+== Git ==
+
+In Git, `arc diff` sends **all commits in a range** for review. By default,
+this range is:
+
+ `git merge-base origin/master HEAD`..HEAD
+
+That's a fancy way of saying "all the commits on the current branch that
+you haven't pushed yet". So, to **create a revision** in Git, run:
+
+ $ nano source_code.c # Make changes.
+ $ git commit # Commit changes.
+ $ arc diff # Creates a new revision out of ALL unpushed commits on
+ # this branch.
+
+Since it uses **all** the commits on the branch, you can make several commits
+before sending your changes for review if you prefer.
+
+You can specify a different commit range instead by running:
+
+ $ arc diff
+
+This means to use the range:
+
+ `git merge-base HEAD`..HEAD
+
+However, this is a relatively advanced feature. The default is usually correct
+if you aren't creating branches-on-branches, juggling remotes, etc.
+
+To **update a revision**, just do the same thing:
+
+ $ nano source_code.c # Make more changes.
+ $ git commit # Commit them.
+ $ arc diff # This prompts you to update revision information.
+
+When your revision has been accepted, you can usually push it like this:
+
+ $ arc land # Merges into master and pushes.
+
+`arc land` makes some assumptions about your workflow which might not be
+true. Consult the documentation before you use it. You should also look at
+`arc amend`, which may fit your workflow better.
+
+= Mercurial =
+
+In Mercurial, `arc diff` sends **all commits in a range** for review. By
+default, this range is changes between the first non-outgoing parent of any
+revision in history and the directory state. This is a fancy way of saying
+"every outgoing change since the last merge". It includes any uncommitted
+changes in the working copy, although you will be prompted to include these.
+
+To **create a revision** in Mercurial, run:
+
+ $ nano source_code.c # Make changes.
+ $ hg commit # Commit changes.
+ $ arc diff # Creates a new revision out of ALL outgoing commits
+ # on this branch since the last merge.
+
+Since it uses **all** the outgoing commits on the branch, you can make several
+commits before sending your changes for review if you prefer.
+
+You can specify a different commit range instead by running:
+
+ $ arc diff
+
+This means to use the range from that commit to the directory state. However,
+this is an advanced feature and the default is usually correct.
+
+To **update a revision**, just do the same thing:
+
+ $ nano source_code.c # Make changes.
+ $ hg commit # Commit changes.
+ $ arc diff # This prompts you to update revision information.
+
+When your revision has been accepted, push it normally. (`arc` does not have
+push integration in Mercurial because it can't force merges and thus can't
+guarantee it will be able to do anything useful.)
+
+= General Information =
+
+This information is not unique to a specific version control system.
+
+== Force Diff Only ==
+
+You can create just a diff (rather than a revision) with `--only` (or
+`--preview`, but this disables other features). You can later use it to create
+or update a revision from the web UI.
+
+== Other Diff Sources ==
+
+You can create a diff out of an arbitrary patch file by using `--raw` and piping
+it to stdin. In most cases this will only create a diff, not a revision. You
+can use the web UI to create or update a revision.
+
+== Force Create / Update ==
+
+`arc` uses information about the working copy (like the path, branch name, local
+commit hashes, and local tree hashes, depending on which version control system
+you are using) to figure out whether you intend to create or update a revision.
+If it guesses incorrectly, you can force it to either create or update a
+revision with:
+
+ $ arc diff --create # Force "create".
+ $ arc diff --update # Force "update".
+
+You can figure out what `arc` believes to be in the working copy with `arc
+which`.
diff --git a/src/docs/userguide/arcanist_new_project.diviner b/src/docs/userguide/arcanist_new_project.diviner
index 11c4c9594a..85807b2127 100644
--- a/src/docs/userguide/arcanist_new_project.diviner
+++ b/src/docs/userguide/arcanist_new_project.diviner
@@ -44,16 +44,49 @@ Other options include:
- **arcanist_configuration**: the name of a subclass of
@{class@arcanist:ArcanistConfiguration} which can add new command flags for
this project or provide entirely new commands.
- - **remote_hooks_installed**: tells Arcanist that you've set up remote hooks
- in the master repository (see @{article:Arcanist User Guide: Repository
- Hooks}).
- **copyright_holder**: used by @{class@arcanist:ArcanistLicenseLinter} to
apply license notices to source files.
+ - **immutable_history**: controls how `arc diff` behaves in Git. See below.
- **phutil_libraries**: map of additional Phutil libraries to load at startup.
See below for details about path resolution, or see
@{article:libphutil Libraries User Guide} for a general introduction to
libphutil libraries.
+= Immutable History =
+
+There are a lot of ways to use git, and Arcanist is flexible enough to handle
+several of them. Git workflows divide into two major groups based on your
+**doctrine of history mutability**.
+
+Choose a **history mutability doctrine** by setting ##"immutable_history"## in
+your ##.arcconfig##. Valid values are ##true## to enforce a **conservative
+history mutability doctrine** or ##false## to enforce a **liberal history
+mutability doctrine**. The default is ##false##.
+
+A **liberal history mutability doctrine** means you rewrite local history. You
+develop in feature branches, but squash or amend before pushing by using ##git
+commit --amend## or ##git rebase -i##. Generally, one idea in the remote is
+represented by one commit.
+
+A **conservative history mutability doctrine** means that you do not rewrite
+local history. This is similar to how Mercurial works. You develop in feature
+branches and push them without squashing commits. You do not use ##git commit
+--amend## or ##git rebase -i##. Generally, one idea in the remote is represented
+by many commits.
+
+Practically, these are the differences you'll see based on your setting:
+
+ - **Mutable**
+ - `arc diff` will prompt you to amend lint changes into HEAD.
+ - `arc diff` will amend the commit message in HEAD after creating a
+ revision.
+ - `arc land` will default to the `--squash` strategy.
+ - **Immutable**
+ - `arc diff` will abort if it makes lint changes.
+ - `arc diff` will not amend the commit message in HEAD after creating a
+ revision.
+ - `arc land` will default to the `--merge` strategy.
+
= How Libraries Are Located =
If you specify an external library to load, like 'examplelib', and use a