rebase --exec: make it work with --rebase-merges
authorJohannes Schindelin <johannes.schindelin@gmx.de>
Thu, 9 Aug 2018 09:41:11 +0000 (02:41 -0700)
committerJunio C Hamano <gitster@pobox.com>
Thu, 9 Aug 2018 15:56:41 +0000 (08:56 -0700)
commit1ace63bc39a339a1616477644d6c43f570716bcb
tree131b45d4acccee003f08d47f0fccdfd41f408e96
parentf0880f77abcbd2dbc948917e995680171eff28b0
rebase --exec: make it work with --rebase-merges

The idea of `--exec` is to append an `exec` call after each `pick`.

Since the introduction of fixup!/squash! commits, this idea was extended
to apply to "pick, possibly followed by a fixup/squash chain", i.e. an
exec would not be inserted between a `pick` and any of its corresponding
`fixup` or `squash` lines.

The current implementation uses a dirty trick to achieve that: it
assumes that there are only pick/fixup/squash commands, and then
*inserts* the `exec` lines before any `pick` but the first, and appends
a final one.

With the todo lists generated by `git rebase --rebase-merges`, this
simple implementation shows its problems: it produces the exact wrong
thing when there are `label`, `reset` and `merge` commands.

Let's change the implementation to do exactly what we want: look for
`pick` lines, skip any fixup/squash chains, and then insert the `exec`
line. Lather, rinse, repeat.

Note: we take pains to insert *before* comment lines whenever possible,
as empty commits are represented by commented-out pick lines (and we
want to insert a preceding pick's exec line *before* such a line, not
afterward).

While at it, also add `exec` lines after `merge` commands, because they
are similar in spirit to `pick` commands: they add new commits.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
sequencer.c
t/t3430-rebase-merges.sh