rebase -i: Failed reword prints redundant error message

The to-do list command `reword` replays a commit like `pick` but lets
the user also edit the commit's log message. If the edited log message
is empty or is found ill-formatted by one of the commit hooks,
git-rebase--interactive prints three error messages to the console.

    1. The git-commit output, which contains all the output from hook
       scripts.
    2. A rebase diagnosis saying at which task on the to-do list it got
       stuck.
    3. Generic presumptions about what could have triggered the error.

The third message contains redundant information and does not add any
enlightenment either, which makes the output unnecessarily longish and
different from the other command's output. For instance, this is what
the output looks like if the log message is empty (contains duplicate
Signed-off-by lines).

    (1.) Aborting commit due to empty commit message. (Duplicate Signed-off-by lines.)
    (2.) Could not amend commit after successfully picking fa1afe1... Some change
    (3.) This is most likely due to an empty commit message, or the pre-commit hook
         failed. If the pre-commit hook failed, you may need to resolve the issue before
         you are able to reword the commit.

Discard the third message.

It is true that a failed hook script might not output any diagnosis but
then the generic message is not of much help either. Since this lack of
information affects the built-in git commands for commit, merge and
cherry-pick first, the solution would be to keep track of the failed
hooks in their output so that the user knows which of her hooks require
improvement.
rebase -i: reword complains about empty commit despite --keep-empty

The to-do list command `reword` replays a commit like `pick` but lets
the user also edit the commit's log message. If `--keep-empty` is passed
as option to git-rebase--interactive, empty commits ought to be replayed
without complains. However, if the users chooses to reword an empty
commit by changing the respective to-do list entry from

    pick fa1afe1 Empty commit

to

    reword fa1afe1 Empty commit

, then git-rebase--interactive suddenly fails to replay the empty
commit. This is especially counterintuitive because `reword` is thought
of as a `pick` that alters the log message in some way but nothing more
and the unchanged to-do list entry would not fail.

Handle `reword` by cherry-picking the named commit and editing the log
message using

    git commit --allow-empty --amend

instead of

    git commit --amend.

Add test.
rebase -i: reword executes pre-commit hook on interim commit

The to-do list command `reword` replays a commit like `pick` but lets
the user also edit the commit's log message. This happens in two steps.
Firstly, the named commit is cherry-picked. Secondly, the commit created
in the first step is amended using an unchanged index to edit the log
message. The pre-commit hook is meant to verify the changes introduced
by a commit (for instance, catching inserted trailing white space).
Since the committed tree is not changed between the two steps, do not
execute the pre-commit hook in the second step.

Specify the git-commit option `--no-verify` to disable the pre-commit
hook when editing the log message. Because `--no-verify` also skips the
commit-msg hook, execute the hook from within git-rebase--interactive
after the commit is created. Fortunately, the commit message is still
available in `$GIT_DIR/COMMIT_EDITMSG` after git-commit terminates.
Caveat: In case the commit-msg hook finds the new log message
ill-formatted, the user is only notified of the failed commit-msg hook
but the log message is used for the commit anyway. git-commit ought to
offer more fine-grained control over which hooks are executed.
rebase -i: Teach do_pick the option --edit

`do_pick` is the git-cherry-pick wrapper in git-rebase--interactive that
is used to implement the to-do list command `pick`. To cater for the
different pick behaviours (like `reword`), `do_pick` accepts several
options not only from the git-cherry-pick but also the git-commit
interface. Add the common option `--edit` to let the user edit the log
message of the named commit.

Loop over `$@` to parse the `do_pick` arguments. Assign the local
variable `edit` if one of the options is `--edit` so that the remainder
of `do_pick` can easily check whether the client code asked to edit the
commit message. If one of the options is unknown, mention it on the
console and `die`. Break the loop on the first non-option and do some
sanity checking to ensure that there exactly two non-options, which are
interpreted by the remainder as `<commit>` and `<title>` like before.

`do_pick` ought to act as a wrapper around `cherry-pick`. Unfortunately,
it cannot just forward `--edit` to the `cherry-pick` command line. The
assembled command line is executed within a command substitution for
controlling the verbosity of `rebase--interactive`. Passing `--edit`
would either hang the terminal or clutter the substituted command output
with control sequences. Execute the `reword` code from `do_next` instead
if the option `--edit` is specified.
rebase -i: Implement reword in terms of do_pick

The to-do list command `reword` replays a commit like `pick` but lets
the user also edit the commit's log message. If one thinks of `pick`
entries as scheduled `cherry-pick` command lines, then `reword` becomes
an alias for the command line `cherry-pick --edit`. The porcelain
`rebase--interactive` defines a function `do_pick` for processing the
`pick` entries on to-do lists. Reimplement `reword` in terms of `do_pick
--edit`.

If the user picks a commit using the to-do list line

    reword fa1afe1 Some change

execute the command `do_pick --edit fa1afe1 "Some change"` which carries
out exactly the same steps as the case arm for `reword` in `do_next` so
far.
rebase -i: Stop on root commits with empty log messages

The command line used to recreate root commits specifies the erroneous
option `--allow-empty-message`. If the root commit has an empty log
message, the replay of this commit shall fail and the rebase shall be
interrupted like for any other commit that is on the to-do list and has
an empty commit message. Remove the option.

The option might have been introduced by copy-and-paste of the first
part of the command line which initializes the authorship of the
sentinel commit. Indeed, the sentinel commit has an empty log message
and this should not trigger a failure, which is why the option
`--allow-empty-message` is correctly specified here.

Add test.
rebase -i: The replay of root commits is not shown with --verbose

The command line used to recreate root commits specifies the erroneous
option `-q` which suppresses the commit summary message. However,
git-rebase--interactive tends to tell the user about the commits it
creates, if she wishes (cf. command line option `--verbose`). The code
parts handling non-root commits or squash commits all output commit
summary messages. Do not make the replay of root commits an exception.
Remove the option.

It is OK to suppress the commit summary when git-commit is used to
initialize the authorship of the sentinel commit because the existence
of this additional commit is a detail of git-rebase--interactive's
implementation. The option `-q` was probably introduced as a
copy-and-paste error stemming from that part of the root commit handling
code.
rebase -i: Root commits are replayed with an unnecessary option

The command line used to recreate root commits specifies the effectless
option `-C`. It is used to reuse commit message and authorship from the
named commit but the commit being amended here, which is the sentinel
commit, already carries the authorship and log message of the processed
commit. Note that the committer email and commit date fields do not
match the root commit either way. Remove the option. However, `-C`
(other than `-c`) does not invoke the editor and the `--amend` option
invokes it by default. Disable editor invocation again by specifying
`--no-edit`.
rebase -i: Commit only once when rewriting picks

The options passed to `do_pick` determine whether the picked commit will
be rewritten or not. If the commit gets rewritten, because the user
requested to edit the commit message for instance, let `pick_one` merely
apply the changes introduced by the commit and do not commit the
resulting tree yet. If the commit is replayed as is, leave it to
`pick_one` to recreate the commit (possibly by fast-forwarding the
head). This makes it easier to combine git-commit options like `--edit`
and `--amend` in `do_pick` because git-cherry-pick does not support
`--amend`.

In the case of `--edit`, do not `exit_with_patch` but assign `rewrite`
to pick the changes with `-n`. If the pick conflicts, no commit is
created which we would have to amend when continuing the rebase. To
complete the pick after the conflicts are resolved the user just resumes
with `git rebase --continue`.

git-commit lets the user edit the commit log message by default. We do
not want that for the rewriting git-commit command line because the
default behaviour of git-cherry-pick is exactly the opposite. Pass
`--no-edit` when rewriting a picked commit. An explicit `--edit` passed
to `do_pick` (for instance, when reword is executed) enables the editor
launch again.

If `rebase--interactive` is used to rebase a complete branch onto some
head, `rebase` creates a sentinel commit that requires special treatment
by `do_pick`. Do not finalize the pick here either because its commit
message can be altered as for any other pick. Since the orphaned root
commit gets a temporary parent, it is always rewritten. Safely use the
rewrite infrastructure of `do_pick` to create the final commit.
rebase -i: Do not die in do_pick

Since `do_pick` might be executed in a sub-shell (a modified author
environment for instance), calling `die` in `do_pick` has no effect but
exiting the sub-shell with a failure exit status. The
git-rebase--interactive script is not terminated. Moreover, if `do_pick`
is called while a squash or fixup is in effect, `die_with_patch` will
discard `$squash_msg` as commit message. Indicate an error in `do_pick`
using return statements and properly kill the script at the call sites.
Remove unused commit message title argument from `do_pick`'s interface.
rebase -i: Teach do_pick the option --amend

`do_pick` is the git-cherry-pick wrapper in git-rebase--interactive that
is used to implement the to-do list commands `pick`, `reword` and
`edit`. To cater for the different pick behaviours (like `squash`),
`do_pick` accepts several options not only from the git-cherry-pick but
also the git-commit interface.

Add the option `--amend` from the git-commit interface to the options
pool of `do_pick`. It creates a new commit for the changes introduced by
the picked commit and the previous one. The previous commit is then
replaced with the new commit. If no other options are specified, the log
message of the previous commit is used.

Be careful when `--amend` is used to pick a root commit because HEAD
might point to the sentinel commit but there is still nothing to amend.
Be sure to initialize `amend` so that commits are squashed even when
git-rebase--interactive is interrupted for resolving conflicts. It is
not a mistake to do the initialization regardless of any conflicts
because `amend` is always cleared before the next to-do item is
processed.
rebase -i: Teach do_pick the option --file

`do_pick` is the git-cherry-pick wrapper in git-rebase--interactive that
is used to implement the to-do list command `pick`, `reword` and `edit`.
To cater for the different pick behaviours (like `squash`), `do_pick`
accepts several options not only from the git-cherry-pick but also the
git-commit interface.

Add the option `--file` from the git-commit interface to the options
pool of `do_pick`. It expects an argument itself which is interpreted as
a file path and takes the commit message from the given file. If
`--file` is passed to `do_pick`, assign the given file path to the local
variable `rewrite_message` and relay the option

    --file "$rewrite_message"

to the git-commit command line which creates the commit.
rebase -i: Prepare for squash in terms of do_pick

Rewrite `squash` and `fixup` handling in `do_next` using the atomic
sequence

    pick_one
    commit

in order to test the correctness of a single `do_squash` or parametrized
`do_pick` and make the subsequent patch reimplementing `squash` in terms
of such a single function more readable.

Might be squashed into the subsequent commit.
rebase -i: Implement squash in terms of do_pick

The to-do list command `squash` and its close relative `fixup` replay
the changes of a commit like `pick` but do not recreate the commit.
Instead they replace the previous commit with a new commit that also
introduces the changes of the squashed commit. This is roughly like
cherry-picking without committing and using git-commit to amend the
previous commit.

The to-do list

    pick   a Some changes
    squash b Some more changes

gets translated into the sequence of git commands

    git cherry-pick a
    git cherry-pick -n b
    git commit --amend

and if git-cherry-pick supported `--amend` this would look even more
like the to-do list it is based on

    git cherry-pick a
    git cherry-pick --amend b.

Since `do_pick` takes care of `pick` entries and the above suggests
`squash` as an alias for `pick --amend`, reimplement `squash` in terms
of `do_pick --amend`. Introduce `$squash_msg` as the commit message via
the `--file` option. When the last commit of a squash series is
processed, the user is asked to review the log message. Pass `--edit` as
additional option in this case. The only difference in the options
passed to git-commit and `do_pick` is the omitted `--no-verify`.
However, `do_pick` does not execute the verification hooks anyway
because it solely replays commits and assumes that they have been
verified before.
rebase -i: Teach do_pick the option --gpg-sign

`do_pick` is the git-cherry-pick wrapper in git-rebase--interactive that
is used to replay the commits mentioned on to-do lists. The git-rebase
interface comes with several options that change how commits are
replayed (for instance, there is a option that asks git-rebase to sign
all replayed commits with the user's GPG key).

To make the replay of commits internally better configurable, add a new
option `--gpg-sign`, which is available from both the git-commit and the
git-cherry-pick interface, to `do_pick`. It appends a GPG signature to
the named commit after it is replayed. The private key used for signing
can either be passed as an argument to the option or left to the user's
gnupg configuration.
rebase -i: Handle rebase option --gpg-sign in do_pick

If `--gpg-sign` is passed to git-rebase, all replayed commits are
GPG-signed. In interactive mode, pretend `--gpg-sign` is passed to every
to-do list command by relaying `gpg_sign_opt` to `do_pick` in `do_next`.
`gpg_sign_opt` is either of the format `-S` or `-S<keyid>` which are
both supported by `do_pick`.
rebase -i: Teach do_pick the option --reset-author

`do_pick` is the git-cherry-pick wrapper in git-rebase--interactive that
is used to implement many of the to-do list commands. Eventually, the
complete `do_pick` interface will be exposed to the user in some form or
another and those commands will become simple aliases for the `do_pick`
options now used to implement them.

Add the git-commit option `--reset-author` to the options pool of
`do_pick`. It rewrites the author date and name of the picked commit to
match the committer date and name.

If `--reset-author` is passed to `do_pick`, set the `rewrite` flag and
relay the option to the git-commit command line which creates the final
commit. If `--amend` is not passed as well, the fresh authorship effect
is achieved by the mere fact that we are creating a new commit.
rebase -i: Teach do_pick the option --signoff

`do_pick` is the git-cherry-pick wrapper in git-rebase--interactive that
is currently used to implement most of the to-do list commands and
offers additional options that will eventually find their way onto to-do
lists.

To extend the repertoire of available options, add the git-commit and
git-cherry-pick option `--signoff` to the `do_pick` interface. It
appends a Signed-off-by: line using the committer identity to the log
message of the picked commit.
rebase -i: Parse to-do list command line options

Read in to-do list lines as

    command args

instead of

    command sha1 rest

so that a to-do list command lines can contain additional arguments
apart from the commit hash and the log message title, which become the
non-options in `args`. Loop over `args`, put all options (an argument
beginning with a dash) in `opts`, stop the loop on the first non-option
and assign it to `sha1`. The loop does not know the options it parses so
that option arguments are not supported at the moment.

Print an error message for unknown or unsupported command line options,
which means an error for all specified options at the moment.

Ensure that the command line options read from the to-do list can
contain spaces and quotes by using git-rev-parse--sq-quote in
combination with eval.
rebase -i: Enable options for pick and reword

pick and reword are atomic to-do list commands in the sense that they
open a new task which is closed after the respective command is
completed. squash and fixup are not atomic. They create a new task which
is not completed until the last squash or fixup is processed.

Remove the `test -z "$opts"` blockade in front of the pick and reword
handling code.

Enable the options `--signoff`, `--gpg-sign`, `--reset-author`,
`--amend`, `--edit` for the to-do list commands pick and reword. The
option `--file` is not yet supported because `do_next` cannot handle
option arguments at the moment. It is true that edit is one of the
atomic commands but it displays hash information when the rebase is
stopped and some options rewrite the picked commit which alters that
information. squash and fixup still do not accept user options.