@@ -403,6 +403,8 @@ reordered, inserted and dropped at will.
403403It is currently only possible to recreate the merge commits using the
404404`recursive` merge strategy; Different merge strategies can be used only via
405405explicit `exec git merge -s <strategy> [...]` commands.
406+ +
407+ See also REBASING MERGES below.
406408
407409-p::
408410--preserve-merges::
@@ -801,6 +803,139 @@ The ripple effect of a "hard case" recovery is especially bad:
801803'everyone' downstream from 'topic' will now have to perform a "hard
802804case" recovery too!
803805
806+ REBASING MERGES
807+ -----------------
808+
809+ The interactive rebase command was originally designed to handle
810+ individual patch series. As such, it makes sense to exclude merge
811+ commits from the todo list, as the developer may have merged the
812+ then-current `master` while working on the branch, only to rebase
813+ all the commits onto `master` eventually (skipping the merge
814+ commits).
815+
816+ However, there are legitimate reasons why a developer may want to
817+ recreate merge commits: to keep the branch structure (or "commit
818+ topology") when working on multiple, inter-related branches.
819+
820+ In the following example, the developer works on a topic branch that
821+ refactors the way buttons are defined, and on another topic branch
822+ that uses that refactoring to implement a "Report a bug" button. The
823+ output of `git log --graph --format=%s -5` may look like this:
824+
825+ ------------
826+ * Merge branch 'report-a-bug'
827+ |\
828+ | * Add the feedback button
829+ * | Merge branch 'refactor-button'
830+ |\ \
831+ | |/
832+ | * Use the Button class for all buttons
833+ | * Extract a generic Button class from the DownloadButton one
834+ ------------
835+
836+ The developer might want to rebase those commits to a newer `master`
837+ while keeping the branch topology, for example when the first topic
838+ branch is expected to be integrated into `master` much earlier than the
839+ second one, say, to resolve merge conflicts with changes to the
840+ DownloadButton class that made it into `master`.
841+
842+ This rebase can be performed using the `--rebase-merges` option.
843+ It will generate a todo list looking like this:
844+
845+ ------------
846+ label onto
847+
848+ # Branch: refactor-button
849+ reset onto
850+ pick 123456 Extract a generic Button class from the DownloadButton one
851+ pick 654321 Use the Button class for all buttons
852+ label refactor-button
853+
854+ # Branch: report-a-bug
855+ reset refactor-button # Use the Button class for all buttons
856+ pick abcdef Add the feedback button
857+ label report-a-bug
858+
859+ reset onto
860+ merge -C a1b2c3 refactor-button # Merge 'refactor-button'
861+ merge -C 6f5e4d report-a-bug # Merge 'report-a-bug'
862+ ------------
863+
864+ In contrast to a regular interactive rebase, there are `label`, `reset`
865+ and `merge` commands in addition to `pick` ones.
866+
867+ The `label` command associates a label with the current HEAD when that
868+ command is executed. These labels are created as worktree-local refs
869+ (`refs/rewritten/<label>`) that will be deleted when the rebase
870+ finishes. That way, rebase operations in multiple worktrees linked to
871+ the same repository do not interfere with one another. If the `label`
872+ command fails, it is rescheduled immediately, with a helpful message how
873+ to proceed.
874+
875+ The `reset` command resets the HEAD, index and worktree to the specified
876+ revision. It is isimilar to an `exec git reset --hard <label>`, but
877+ refuses to overwrite untracked files. If the `reset` command fails, it is
878+ rescheduled immediately, with a helpful message how to edit the todo list
879+ (this typically happens when a `reset` command was inserted into the todo
880+ list manually and contains a typo).
881+
882+ The `merge` command will merge the specified revision into whatever is
883+ HEAD at that time. With `-C <original-commit>`, the commit message of
884+ the specified merge commit will be used. When the `-C` is changed to
885+ a lower-case `-c`, the message will be opened in an editor after a
886+ successful merge so that the user can edit the message.
887+
888+ If a `merge` command fails for any reason other than merge conflicts (i.e.
889+ when the merge operation did not even start), it is rescheduled immediately.
890+
891+ At this time, the `merge` command will *always* use the `recursive`
892+ merge strategy, with no way to choose a different one. To work around
893+ this, an `exec` command can be used to call `git merge` explicitly,
894+ using the fact that the labels are worktree-local refs (the ref
895+ `refs/rewritten/onto` would correspond to the label `onto`, for example).
896+
897+ Note: the first command (`label onto`) labels the revision onto which
898+ the commits are rebased; The name `onto` is just a convention, as a nod
899+ to the `--onto` option.
900+
901+ It is also possible to introduce completely new merge commits from scratch
902+ by adding a command of the form `merge <merge-head>`. This form will
903+ generate a tentative commit message and always open an editor to let the
904+ user edit it. This can be useful e.g. when a topic branch turns out to
905+ address more than a single concern and wants to be split into two or
906+ even more topic branches. Consider this todo list:
907+
908+ ------------
909+ pick 192837 Switch from GNU Makefiles to CMake
910+ pick 5a6c7e Document the switch to CMake
911+ pick 918273 Fix detection of OpenSSL in CMake
912+ pick afbecd http: add support for TLS v1.3
913+ pick fdbaec Fix detection of cURL in CMake on Windows
914+ ------------
915+
916+ The one commit in this list that is not related to CMake may very well
917+ have been motivated by working on fixing all those bugs introduced by
918+ switching to CMake, but it addresses a different concern. To split this
919+ branch into two topic branches, the todo list could be edited like this:
920+
921+ ------------
922+ label onto
923+
924+ pick afbecd http: add support for TLS v1.3
925+ label tlsv1.3
926+
927+ reset onto
928+ pick 192837 Switch from GNU Makefiles to CMake
929+ pick 918273 Fix detection of OpenSSL in CMake
930+ pick fdbaec Fix detection of cURL in CMake on Windows
931+ pick 5a6c7e Document the switch to CMake
932+ label cmake
933+
934+ reset onto
935+ merge tlsv1.3
936+ merge cmake
937+ ------------
938+
804939BUGS
805940----
806941The todo list presented by `--preserve-merges --interactive` does not
0 commit comments