rbt should find repositories based on mirror_path

"rbt post -u" doesn't work if the repository is being identified using a
mirror_path - get_repository_id returns None which causes an error trying to do
the update.

The patch matches the logic in commands/setup_repo.py and clients/svn.py.

Testing Done:
Tested locally against reviewboard 1.7 - repo with the path of
http://svn.DOMAIN/svn/foo and mirror_path of http://svn/svn/foo works with `rbt
post -u` when my local checkout is http://svn/svn/foo

Reviewed at https://reviews.reviewboard.org/r/5468/
Associate -p arg with PUBLISH config key.

When implementing the rbt arguments, we missed including PUBLISH as a config
key for the -p argument. This meant that users who had this in their
.reviewboardrc wouldn't get the desired behavior when using 'rbt post'.
Trivial fix.

Fixes bug 3271.
Merge branch 'release-0.5.x'
Don't attempt to post changenums when posting a commit_id fails.

Due to a bug in the Review Board 2.0 betas, posting a new review request
with a commit ID matching an existing commit ID would cause us to
receive an error saying the change number was in use. We'd then try to
post again using the changenum instead of commit_id, which would fail
due to being None.

Part of this needs to be fixed in Review Board (as we shouldn't be
getting this error unless we're trying to create from that commit ID),
but we can also handle this better by falling back to the more general
error case.
Add options to override GUESS_* items from .reviewboardrc

If your .reviewboardrc contains GUESS_FIELDS=True, GUESS_DESCRIPTION=True, or
GUESS_SUMMARY=True, there's no way to override these on a per-submission
basis (for example, if you want to update a review request, but don't
want to update the descipriont).

Add --no-guess-{fields,description,summary} options to rbt post, which
override these values from .reviewboardrc

Reviewed at https://reviews.reviewboard.org/r/5262/
Revert "Add options to override GUESS_* items from .reviewboardrc"

This reverts commit 6259968684baf142be36974022b661ca42361baf.
Don't include error stream output in git diffs

We ran into a problem where the diff is generated properly and git doesn't
throw an error, but it prints warnings to stderr during the diff generation.
The error stream content is included in the diff and this creates a corrupted
diff, which causes breakage on the Review Board server. This patch makes it so
that the generated diffs don't include the stderr stream content.

Sample Warning:
   warning: CRLF will be replaced by LF in pom.xml.
   The file will have its original line endings in your working directory.

Testing Done:
We tested that the scenario described no longer occurs when the stderr is not
included in the diff.

Reviewed at https://reviews.reviewboard.org/r/5615/
Merge branch 'release-0.5.x'
Improve guess support in rbt post.

This adds new abilities to rbt post's guess fields support. The old
guess support was a boolean state, which only supported opt-in and not
opt-out. That is, if GUESS_FIELDS was set to True in .reviewboardrc, it
couldn't be turned off when posting.

It's now a tri-state of "yes", "no", and "auto", which can be set on the
command line or .reviewboardrc.

If "yes", it behaves as before, with the fields being updated from the
commit message.

If "no", guessing will be turned off (which allows the command line to
override the config file).

If "auto", guessing will be turned on only for new review requests, but
turned off when updating.

If no --guess-* options or configuration variables are set, the
default will be "auto", making for a nicer experience when posting brand
new review requests.

If an old-style --guess-* option is passed without a value (in the form
of --guess-*=value or -gvalue), then the prior logic of forcing guessing
will be used. That is, "yes" is implied.

While "yes", "no", and "auto" are all valid values, we still support
True and False in .reviewboardrc, for backwards-compatibility.
Improve logging for RBTools.

The API/command rewrite in 0.5 regressed our log output, making it a bit
harder to gather useful debug information and to nicely show logging of
various levels.

Upon starting, we log a bunch of debug information, in order to help
with support requests. This matches what post-review used to show.

We now format different log levels in different ways.

Debug messages once again have a ">>>" prefix to help distinguish them
from other output.

Info messages are shown just like print statements, with no prefixes.

Warning and higher are in the form of "LEVEL: message". This is a lot
nicer to look at when there's an error, since we now show
"ERROR: <blah>" instead of "ERROR:root:<blah>".

The resulting logging looks like:

>>> This is debug
This is info
WARNING: This is warning
ERROR: This is error
CRITICAL: This is critical
Switch to using argparse for argument parsing.

argparse is the successor to optparse, and has a lot of nice additions
we may want to take advantage of. It knows how to do things like
optional values to arguments flags, variable argument values, and
"positional arguments" (such as a command name), reducing the amount of
work we have to do.

The two are pretty compatible, allowing for most of the porting effort
to remain under the hood. New commands can certainly take advantage of
the new support though.

We still maintain our own Option and OptionGroup wrappers, which we
still need in order to map to configuration keys.

argparse is natively available on Python 2.7 or higher. For older
versions, we depend on the 'argparse' package from PyPI, which provides
compatibility with Python 2.7's argparse.
Add some logging when check_install fails.

Right now, if the command-line tools aren't available in the path, rbtools will
just skip that backend silently. This change adds some debug logging that
indicates which backends are skipped due to missing dependencies.

Testing done: Ran unit tests.

Fixes bug 3187.

Reviewed at https://reviews.reviewboard.org/r/5625/
Fix git-svn (and git-perforce) with parent diffs.

There were a few bugs making it impossible to use --parent with git-svn and
git-perforce checkouts. The first of which is that the make_*_diff methods
needed to have access to the merge base, rather than the base of the individual
diff. I've plumbed this through so that we can properly determine the upstream
revision to include in the diff headers.

The other problem was that the git-svn code was mistakenly using --parent to
mean the upstream branch rather than --tracking-branch.

Testing done:
Posted changes with a git-svn checkout, both for a single branch off of master,
as well as using --parent to post a change with un-committed parent revisions.

Fixes bug 3273.

Reviewed at https://reviews.reviewboard.org/r/5628/
Better handle replaced files in Subversion

A few issues noticed with how SVN client deals with replaced files. Replaced
file is a file copied as a part of a directory, then removed and added from
another source. E.g.

$ svn cp A B  # Copy a directory
$ svn rm B/file1
$ echo > B/file1
$ svn add B/file1  # B/file1 is replaced without history
$ svn rm B/file2
$ svn cp ^/some/other/file B/file2  # B/file2 is replaced with history

First, a new file is typically displayed in one column in RB. However, the diff
for B/file1 has two columns, with the left one showing the path to A/file1 -
and no file text. Since A/file1 is no longer related to B/file1 after
replacement, the right solution would be to just consider B/file1 a new file.
To distinguish such files, find_copy_from could check the "Schedule" field in
'svn info' output. As long as a file is still a part of the directory copy
(even if it is modified), it will have a "Schedule: normal" line in its svn
info.

Second, if a file is replaced with history (e.g. B/file2 above), by default
'svn diff' will produce a patch against the the file copied as a part of
directory (i.e. against A/file1 in the example above). Then it's massaged by
post-review/rbt to replace the source of the copy (to /some/other/file in the
example above). When such diff is displayed by RB, it fails to apply as RB
attempts to apply it to /some/other/file while the diff was generated against
A/file2.

The solution for that is to use 'svn diff --notice-ancestry', which makes the
diff for unrelated files (i.e., replaced files) to be generated as delete +
add. In this case, the 'add' part is generated against /some/other/file and RB
displays it correctly. However, the 'delete' part needs to be special-cased in
handle_renames: for it to apply, we must keep the file names as they were
generated by 'svn diff'. Thus, cache both from/to lines for each file and look
at the first diff hunk. If it is a complete removal of a file (@@ -1,X +0,0 @@)
- keep the from/to lines intact. Otherwise, find the source of the copy and
replace it in the diff as it was done before.

Third, the status for the replaced files is displayed as "R  +" or "RM +". SVN
client only checks for "A  +" at this time when it verifies whether the patch
being posted has files with history. Replace that check with just checking the
column 4 for '+' character.

Testing Done:
Tested on 0.5.7, then patch applied to 0.6.0. I would appreciate if you could
test it on 0.6.0.

Reviewed at https://reviews.reviewboard.org/r/5648/
Add hooks module, containing utility functions common to hook scripts.

This is a new 'hooks' module in RBTools. rbtools/hooks/common.py contains
functions common to all hook scripts, and rbtools/hooks/git.py contains
functions for Git hook scripts.

Testing Done:
- Tested the functions individually, and got the expected results.
- More testing was done in https://reviews.reviewboard.org/r/5403/ for the Git
  post-receive and pre-receive hook scripts that use this new module.

Reviewed at https://reviews.reviewboard.org/r/5543/
Add Git hooks to close review requests automatically and to check if each review request is approved.

There are two Git hook scripts in this review request.

The first is a Git post-receive hook script (git-hook-set-submitted) that will
automatically close review requests as "submitted" after a push.

The second is a Git pre-receive hook script (git-hook-check-approval) that
checks if each review request corresponding to a commit has been approved. A
commit that has no corresponding review request is marked as being unapproved
(optional). If any of the checked commits is unapproved, it declines the push
(optional).

In both, to determine which review requests should be processed, it scans
through each commit's commit message for the following strings
(case-insensitive): "Reviewed at <reviewboard_url>/r/<id>" or "Review request
#<id>".

Testing Done:

Created a local Git repository, added the hook, and tested different pushes
from a cloned repository:
- Commits with and without a review request ID in the commit message
- Merge commits (3-way merge, fast-forward merge)
- Branch deletion (no "fatal" error shows up)
- Branch creation (1 branch with 2 initial commits -- all review requests are
  closed properly)
- Commits referencing the same review request ID (close_review_request is
  executed only once, and the change description displays all commits that
  referenced that particular review request ID)
- Commit pushed to multiple branches (e.g., someone commits on branch1, merges
  branch1 into master, pushes both branch1 and master -- see attached
  screenshot. close_review_request is executed once.)
- Branch creation and commit pushed to multiple branches (e.g., someone creates
  branch1, commits on branch1, merges branch1 into master, pushes both branch1
  and master)

All test cases above showed the expected behaviour.

Additionally, for the pre-receive hook:
- Commit with review request ID that is approved (push is accepted)
- Commit with review request ID that is not approved, due to open issues or a
  lack of "Ship It!"s (push is declined)
- Commit without a review request ID in the commit message (push is declined)
- Multiple commits, where one of the review requests is not approved (push is
  declined)
- Multiple commits, where all of the review requests are approved (push is
  accepted)
- Set REQUIRE_REVIEW_REQUESTS to False, and pushed a commit without a review
  request ID in the commit message (push is accepted)
- Set DECLINE_UNAPPROVED_PUSH to False, and pushed commits that are not
  approved (push is accepted)

Reviewed at https://reviews.reviewboard.org/r/5403/
Add an __init__.py to rbtools/hooks/

This wasn't included because of our poor handling of adding empty files.
Rename the doc file extensions from .txt to .rst.

This gets us onto .rst for RBTools as the official doc extension, making
it easier to review, and allowing for more consistency between the
modules.
Switch the doc building to look up .rst instead of .txt files.
Add release notes for RBTools 0.6.

This details all the changes we made in 0.6, which is a pretty
substantial release.

Reviewed at https://reviews.reviewboard.org/r/5675/