@title Arcanist User Guide
@group userguide

Guide to Arcanist, a command-line interface to Phabricator.

Arcanists provides command-line access to many Phabricator tools (like
Differential, Files, and Paste), integrates with static analysis ("lint") and
unit tests, and manages common workflows like getting changes into Differential
for review.

A detailed command reference is available by running ##arc help##. This
document provides a high level overview of common workflows.

Arcanist has technical, contributor-focused documentation here:
<http://www.phabricator.com/docs/arcanist/>

= Overview =

Arcanist is a wrapper script that sits on top of other tools (e.g.,
Differential, linters, unit test frameworks, git, Mercurial, and SVN) and
provides a simple command-line API to manage code review and some related
revision control operations.

Arcanist allows you to do things like:

  - get detailed help about available commands with ##arc help##
  - send your code to Differential for review with ##arc diff##
  - show pending revision information with ##arc list##
  - find likely reviewers for a change with ##arc cover##
  - apply changes in a revision to the working copy with ##arc patch##
  - download a patch from Differential with ##arc export##
  - update Git commit messages after review with ##arc amend##
  - commit SVN changes with ##arc commit##
  - push Git changes with ##arc land##
  - view enhanced information about Git branches with ##arc branch##

Once you've configured lint and unit test integration, you can also:

  - check your code for syntax and style errors with ##arc lint##
  - run unit tests that cover your changes with ##arc unit##

Arcanist integrates with other tools:

  - upload and download files with ##arc upload## and ##arc download##
  - create and view pastes with ##arc paste##

Arcanist has some advanced features as well, you can:

  - execute Conduit method calls with ##arc call-conduit##
  - create or update libphutil libraries with ##arc liberate##
  - activate tab completion with ##arc shell-complete##
  - install arc as a pre-commit hook with ##arc svn-hook-pre-commit## or
    ##arc git-hook-pre-receive##
  - ...or extend Arcanist and add new commands.

Except where otherwise noted, these workflows are generally agnostic to the
underlying version control system and will work properly in git, Mercurial, or
SVN repositories.

= Installing Arcanist =

Arcanist is meant to be installed on your local machine or development server --
whatever machine you're editing code on. It runs on Linux, Mac OS X, and
Windows (see @{article:Arcanist User Guide: Windows}).

Arcanist is written in PHP, so you need to install the PHP CLI first if you
don't already have it. Arcanist should run on PHP 5.2 and newer. If you don't
have PHP installed, you can download it from <http://www.php.net/>.

To install Arcanist, pick an install directory and clone the code from GitHub:

  some_install_path/ $ git clone git://github.com/facebook/libphutil.git
  some_install_path/ $ git clone git://github.com/facebook/arcanist.git

This should leave you with a directory structure like this

  some_install_path/    # Wherever you chose to install it.
    arcanist/           # Arcanist-specific code and libraries.
    libphutil/          # A shared library Arcanist depends upon.

Now add ##some_install_path/arcanist/bin/## to your PATH environment variable.
When you type "arc", you should see something like this:

  Usage Exception: No command provided. Try 'arc help'.

If you get that far, you've done things correctly. If you get an error or have
trouble getting this far, see these detailed guides:

  - On Windows: @{Arcanist User Guide: Windows}
  - On Mac OS X: @{Arcanist User Guide: Mac OS X}

The code changes quickly, so remember to update regularly, by running
`git pull` on the two directories:

  some_install_path/arcanist/ $ git pull
  some_install_path/libphutil/ $ git pull

== Installing Arcanist for a Team ==

Arcanist changes quickly and doesn't currently have an auto-update mechanism,
so it can be something of a headache to get it installed and keep people up to
date. Here are some approaches you might be able to use:

  - Facebook does most development on development servers, which have a standard
    environment and NFS mounts. Arcanist and libphutil themselves live on an
    NFS mount, and the default `.bashrc` adds them to the PATH. Updating the
    mount source updates everyone's versions, and new employees have a working
    `arc` when they first log in.
  - Another common approach is to write an install script as an action into
    existing build scripts, so users can run `make install-arc` or
    `ant install-arc` or similar.
  - In general, if this sucks and is causing you pain, let us know (see
    @{article:Give Feedback! Get Support!}). We're planning to improve this at
    some point, but it's somewhat complicated to get right. While it can take a
    little time to set up, we aren't getting feedback that it's a persistent
    pain point, so it hasn't been a priority.

== Installing Tab Completion ==

If you use ##bash##, you can set up tab completion by adding something like this
to your ##.bashrc##, ##.profile## or similar:

  source /path/to/arcanist/resources/shell/bash-completion

= Running Arcanist =

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.

== 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.
