Allow running `arc diff` without `git commit`

Summary:
There's quite some logic in here:

- It automatically decides whether to create a new commit or amend.
- It partially respects 'default-relative-commit'.
- However if it points to a closed revision then it creates a new commit.

Resolves T2025.

Test Plan:
`arc diff` on:

- Clean committed repository.
- Dirty repository without commit since 'default-relative-commit'.
- Dirty repository with non-revision commit since 'default-relative-commit'.
- Dirty repository with revision commit since 'default-relative-commit'.
- `arc diff HEAD^` on dirty repository on top of closed revision.

Reviewers: epriestley, btrahan

Reviewed By: epriestley

CC: aran, Korvin

Maniphest Tasks: T2025

Differential Revision: https://secure.phabricator.com/D3967
Reintroduce `arc diff --advice`

Summary:
Some users want be stopped even if there are lint advices.

NOTE: Deleted by D3364.

Test Plan:
On diff with lint advice:

  $ arc diff --preview # advice just printed
  $ arc diff --preview --advice # excuse required

Reviewers: epriestley

Reviewed By: epriestley

CC: akramer, aran, Korvin

Differential Revision: https://secure.phabricator.com/D3982
make arcanist backwards compatible with various conduit versions

Summary: pragmatism wins the day, though I think eventually we might want something really fancy to deal with arcanist and conduit not being up to date with respect to one another

Test Plan: php -l

Reviewers: epriestley

Reviewed By: epriestley

CC: zeeg, aran, Korvin

Maniphest Tasks: T2088

Differential Revision: https://secure.phabricator.com/D3988
Don't use empty commit message in commit from `arc diff`

Summary:
There was a bug in Git: https://github.com/git/git/commit/d9a935

Also fix a bug with discovering existing commits.

Test Plan:
  $ arc diff # yes
  # abort
  $ arc diff # didn't see fatal

Reviewers: epriestley

Reviewed By: epriestley

CC: aran, Korvin

Maniphest Tasks: T2025

Differential Revision: https://secure.phabricator.com/D3983
Change lint_engine to lint.engine

Summary: Also unit_engine.

Test Plan: None.

Reviewers: epriestley

Reviewed By: epriestley

CC: aran, Korvin, aurelijus

Differential Revision: https://secure.phabricator.com/D4001
Don't amend commits with different author

Summary: Also delete extra newlines.

Test Plan:
  $ arc diff # on top of my commit

Reviewers: epriestley

Reviewed By: epriestley

CC: aran, Korvin

Maniphest Tasks: T2025

Differential Revision: https://secure.phabricator.com/D3996
Allow caching lint results

Summary:
There is one big decision: How to get linters version.
I've created `getCacheVersion()` which is supposed to be bumped every time engine or any linter is changed.
This is not very nice but the other alternative (detect this automatically) seems worse:

- The engine may be outside repo and may or may not be under version control so getting its version through something like `git log` may not be even possible.
- If it is in the same repo then every rebase will obsolete the whole cache.

Even though bumping the version manually is PITA I still think it's a better solution.

Test Plan:
  $ time arc lint --cache 1
  # verified file
  $ arc arc lint --cache 1
  # added some debug output to see the cached results
  # also observed better time (.57 s instead of 2.19 s)

Reviewers: epriestley

Reviewed By: epriestley

CC: aran, Korvin

Maniphest Tasks: T2036

Differential Revision: https://secure.phabricator.com/D4006
Emit advice for TODO in Phutil linter

Summary:
Let's try this.
It may be useful to see this together in Differential overview.

Test Plan: Linted a file with TODO.

Reviewers: epriestley

Reviewed By: epriestley

CC: aran, Korvin

Maniphest Tasks: T744

Differential Revision: https://secure.phabricator.com/D4014
Fix getting changed files in Git
Fix some arcanist warnings

Summary:
  - Rename some very old variables.
  - Wrap some contributed lines.

Test Plan: `arc lint` / `arc unit`. Viewed a diff in an uncacheable mode to verify intraline behavior.

Reviewers: vrana

Reviewed By: vrana

CC: aran

Differential Revision: https://secure.phabricator.com/D4018
Set cache version per linter

Summary: Also delete cache with `--cache 0`.

Test Plan:
  $ arc lint --lintall --cache 1
  $ cat .git/arc/lint-cache.json
  $ arc lint --lintall --cache 1 # with debug output

Reviewers: epriestley

Reviewed By: epriestley

CC: aran, Korvin

Maniphest Tasks: T2036

Differential Revision: https://secure.phabricator.com/D4013
Parse "--help" correctly in `arc`

Summary:
We delegate parsing to `PhutilArgumentParser` but then skip the parts of the code which do something with this flag.

In particular, `arc --help list` just runs `arc list`.

See https://github.com/facebook/arcanist/issues/58

Test Plan: Ran `arc --help`, `arc list --help`, `arc --help list`, `arc --help help --help`. Got expected help in all cases.

Reviewers: vrana, chad, btrahan

Reviewed By: chad

CC: aran

Differential Revision: https://secure.phabricator.com/D4023
Prefer Mercurial and Git over Subversion in discovering repository

Summary: `svn info` is the slowest command for discovering repository (up to 300 ms) and Subversion is probably the least used repository type with Arcanist. Let's discover it last.

Test Plan:
  $ arc lint --trace

Reviewers: epriestley

Reviewed By: epriestley

CC: aran, Korvin

Differential Revision: https://secure.phabricator.com/D4039
Provide a method for getting Git SVN revision

Summary: I plan to use it in `save_lint.php`.

Test Plan:
  $api->getUnderlyingWorkingCopyRevision(); // In Git SVN repo

Reviewers: epriestley

Reviewed By: epriestley

CC: aran, Korvin

Differential Revision: https://secure.phabricator.com/D4054
Improve getting Git author

Summary:
It has one more than source, see http://www.kernel.org/pub/software/scm/git/docs/git-commit-tree.html#_commit_information.
Also 'user.name' may not be set at all.
Also `git config` returns non-zero for non-existing value.

Test Plan:
  var_dump($api->getAuthor());

Reviewers: epriestley

Reviewed By: epriestley

CC: aran, Korvin

Differential Revision: https://secure.phabricator.com/D4053
Add a very basic Scala (SBT) linter.

Summary:
SBT is the most common Scala buildsystem. This adds an extremely basic and
slightly horrible linter to check SBT's output for warnings and errors.

Test Plan:
Tested this with a Scala project I've been working on for some time.
It seemed relatively sane.

Reviewers: epriestley

Reviewed By: epriestley

CC: aran, Korvin

Differential Revision: https://secure.phabricator.com/D4064
Break arc land run() into smaller functions

Summary:
Refactor the arc land code into several
functions so it's easier to maintain. This is in
preparation for adding hg support to arc land
in my next commit.

Without this refactor, adding hg support makes the run()
function too big.

Test Plan:
Set up a git repo and clone with a branch scenario.
Example: https://secure.phabricator.com/P614
Ran and verified:
arc land
arc land --keep-branch
arc land --merge
arc land --merge --keep-branch
arc land --hold
arc land --revision <another phabricator rev>

Reviewers: epriestley

Reviewed By: epriestley

CC: dschleimer, sid0, aran, Korvin

Differential Revision: https://secure.phabricator.com/D4056
canRun should return false on scala linter instead of raising an exception

Summary:
This was causing the following error in environments that didnt have scala configured:

Some linters failed:
   - ArcanistScalaSBTLinter: ArcanistUsageException: This directory does not appear to be maintained by SBT, as we can't seem to find a working build file (project/Build.scala or build.sbt).

Test Plan: .

Reviewers: epriestley

Reviewed By: epriestley

CC: aran, Korvin

Differential Revision: https://secure.phabricator.com/D4070
Allow setting lint cache granularity

Summary:
We can add `GRANULARITY_DIRECTORY` and `GRANULARITY_REPOSITORY` later.
Repository granularity may use current commit + changes.
Directory would need to use hashes of all files in dir which would be quite expensive.

Test Plan:
  $ echo '<?php class A extends B {}' > A.php
  $ arc lint --cache 1
  $ arc lint --cache 1
  $ echo '<?php class B {}' > B.php
  $ arc lint --cache 1
  $ arc lint --cache 1
  $ rm B.php
  $ arc lint --cache 1
  $ arc lint --cache 1

Reviewers: epriestley

Reviewed By: epriestley

CC: aran, Korvin

Differential Revision: https://secure.phabricator.com/D4021
Restore order of operations after D4056

Summary:
See discussion in D4056. In `findRevision()` we call `loadWorkingCopyDifferentialRevisions()`. However, this method depends upon the state of the working copy, because the end of the commit range it examines is HEAD. Prior to D4056 we checked out the target branch before calling `findRevision()`; after D4056 we call it earlier.

This isn't problematic in the `arc land` case, but in the `arc land <branch>` case it means we may fail to identify a revision, or identify the wrong revision, because HEAD isn't where we expect it to be.

Instead, unconditionally check out the target branch before finding the revision.

See <http://dl.dropbox.com/u/116385/Slingshot/Pictures/Screen%20Shot%202012-12-03%20at%203.43.45%20PM.png> for a transcript of the issue.

Test Plan: Reproduced issue as per link above. Ran `arc land --keep-branch --hold somebranch` successfully after this patch.

Reviewers: DurhamGoode, zeeg

Reviewed By: DurhamGoode

CC: aran

Differential Revision: https://secure.phabricator.com/D4072