rebase -i: remove no-op do_with_author git commit --amend

The author script is a file in the state directory that contains
assignments of the environment variables

    GIT_AUTHOR_NAME
    GIT_AUTHOR_EMAIL
    GIT_AUTHOR_DATE

to be evaluated by the shell. It is used to store author information
and has two applications in `git-rebase--interactive.sh`. Firstly,
the authorship of squash commits is read from it while the squash
commit is being amended step by step. Secondly, after conflict
resolution `git rebase --continue` restores the author information of
the original commit by sourcing the author script. For the
assignments of the git environment variables to take effect,
git-rebase--interactive executes the respective git-commit commands
wrapped in `do_with_author`. That shell function executes the named
command in a subshell that exports the git environment variables.

Since

    git commit --amend

has been used instead of

    git reset --soft HEAD^
    git commit

to amend squash commits, wrapping git-commit in `do_with_author` has
become a no-op because, unless the `--reset-author` option is
specified, `git commit --amend` ignores the user environment and
reuses the authorship of the commit it amends. To make the code
clearer and until we decide to use other authorships for squash
commits than the one of the first commit, unwrap `git commit
--amend`.
rebase -i: prepare for squash in terms of do_pick --amend

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

    pick_one
    commit

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

Do not call `rm -f "$GIT_DIR"/MERGE_MSG` since it has no effect on
the state after git-rebase--interactive terminates. The option `-F`
makes git-commit ignore `MERGE_MSG` for the log message. If
git-commit succeeds, `MERGE_MSG` is removed, and if it fails,
`MERGE_MSG` is overwritten by the error sequence `die_failed_squash`.
In summary, removing `MERGE_MSG` neither influences the squash commit
message nor the file state after git-commit returns.

Moreover, `pick_one` ignores `$GIT_DIR/SQUASH_MSG` and does not touch
`$squash_msg` so that it is correct to execute `pick_one` immediately
before git-commit.

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: explicitly distinguish replay commands and exec tasks

There are two kinds of to-do list commands available. One kind
replays a commit (`pick`, `reword`, `edit`, `squash` and `fixup` that
is) and the other executes a shell command (`exec`). We will call the
first kind replay commands.

The two kinds of tasks are scheduled using different line formats.
Replay commands expect a commit hash argument following the command
name and exec concatenates all arguments to assemble a command line.

Adhere to the distinction of formats by not trying to parse the
`sha1` field unless we are dealing with a replay command. Move the
replay command handling code to a new function `do_replay` which
assumes the first argument to be a commit hash and make no more such
assumptions in `do_next`.
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 to-do list command lines can specify 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`. For instance, the to-do list

    reword --signoff fa1afe1 Some change

is parsed as `command=reword`, `opts= '--signoff'` (including the
single quotes and the space for evaluation and concatenation of
options), `sha1=fa1afel` and `rest=Some change`. The loop does not
know the options it parses so that options that take an argument
themselves are not supported at the moment. Neither are options that
contain spaces because the shell expansion of `args` in `do_next`
interprets white space characters as argument separator.

Print an error message for unknown or unsupported command line
options, which means an error for all specified options at the
moment. Cleanly break the `do_next` loop by assigning a reason to the
local variable `malformed`, which triggers the unknown command code
in `do_replay`. Move the error code to the beginning of `do_replay`
so that unknown commands are reported before bad options are as only
the first error we come across is reported. For instance, the to-do
list from above produces the error

    Unknown 'reword' option: --signoff
    Please fix this using 'git rebase --edit-todo'.

The to-do list is also parsed when the commit hashes are translated
between long and short format before and after the to-do list is
edited. Apply the same procedure as in `do_replay` with the exception
that we only care about where the options stop and the commit hash
begins. Do not reject any options when transforming the commit
hashes.

Enable the specification of to-do list command line options in
`FAKE_LINES` the same way this is accomplished for command lines
passed to `exec`. Define a new `fake_editor.sh` that edits a static
to-do list instead of the one passed as argument when invoked by
git-rebase. Add a test case that checks that unknown options are
refused and can be corrected using `--edit-todo`.
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. Do not even source the ident information in that case
because the user shell might have already exported the respective
environment variables.
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: do not overwrite user author information

The shell function `get_author_ident_from_commit` defined by
git-sh-setup retrieves the author information from the named commit
and returns assignments of the environment variables

    GIT_AUTHOR_NAME
    GIT_AUTHOR_EMAIL
    GIT_AUTHOR_DATE

ready for evaluation by the shell.

This interface is used in conjunction with the so-called author
script which is a git-rebase--interactive state file that contains
the `get_author_ident_from_commit` output. It is sourced when `git
rebase --continue` is executed after conflict resolution to retain
the original commit authorship.

The variable assignments are only exported by the subshell that
executes the git-commit command line that commits the resolved
conflicts. That is taken care of by wrapping the git-commit call in
`do_with_author`. However, this is not enough protection from
modifying the git environment variables unintentionally because the
user running git-rebase could have already exported those herself.
And therefore, a bare git-commit could result in an authorship that
is neither intended by the user nor by git-rebase--interactive.

While it is not an issue now (either `do_with_author`,
git-cherry-pick or `--amend` are used to create commits), the
unnecessary loss of the author name and e-mail copied from the user
environment, and the unneeded fixing of the author date might become
a problem when we decide to support something similar to
`--reset-author` or `--ignore-date in interactive git-rebase.

Do not assign the git environment variables until in the
`do_with_author` subshell.
rebase -i: refuse to commit when resuming with updated head

If git-rebase--interactive fails to apply the changes introduced by a
commit due to conflicts, it interrupts the rebase process and gives
the user a shell to resolve the conflicts manually. The process is
resumed when the user executes `git rebase --continue`. If the index
has changes, the script assumes that those are to be committed under
the authorship and with the log message of the commit it tried to
replay last. However, that assumption is most likely incorrect if the
user has already committed the resolved changes herself. To prevent
committing unrelated changes under the wrong authorship and with the
wrong log message, at least check that HEAD is still at the same
commit by tracking the hash of the last replayed commit. A similar
check already happens before `git rebase --continue` amends the
previous commit after an `edit` or a conflicted `squash` command.
rebase -i: enable --signoff, --reset-author for pick, reword, edit

Lift the general unknown option blockade for the `pick`, `reword` and
`edit` commands. If `do_cmd` comes across one of the options
`--signoff` and `--reset-author` while parsing a to-do entry and the
scheduled command is either `pick` or `reword`, relay the option to
`do_pick`.

Remember to add Signed-off-by: and to reset the authorship even when
the rebase is interrupted for conflict resolution and `git rebase
--continue` creates the commit. Employ the same mechanism that is
used to remember amending an interim squash commit after conflict
resolution or a commit after editing. If a line option was specified,
create the files `signoff` and `resetauthor` respectively in the
state directory. While `signoff` is handled by simply specifying the
`--signoff` option when creating the commit, the `resetauthor` case
is somewhat more involved. The author script contains the author
information of the replayed commit. Renewing the authorship means
using the user environment for the authorship so that we need to skip
the author script if `resetauthor` exists and we are not amending. If
we are amending, `--reset-author` must be passed to git-commit
because otherwise the authorship of HEAD would be used.

`do_pick` options like `--gpg-sign` and `--file` are not yet
supported because `do_cmd` cannot handle option arguments and options
with spaces at the moment. `squash` and `fixup` still do not accept
user options as the interplay of `--reset-author` and the author
script is yet to be determined.

Document the new options by listing them in the to-do help and giving
a usage example in the "INTERACTIVE MODE" section of the git-rebase
man page.

Add tests.