Skip to content

Commit 25cff9f

Browse files
dschogitster
authored andcommitted
rebase -i --rebase-merges: add a section to the man page
The --rebase-merges mode is probably not half as intuitive to use as its inventor hopes, so let's document it some. Signed-off-by: Johannes Schindelin <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 7543f6f commit 25cff9f

File tree

1 file changed

+135
-0
lines changed

1 file changed

+135
-0
lines changed

Documentation/git-rebase.txt

Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -403,6 +403,8 @@ reordered, inserted and dropped at will.
403403
It is currently only possible to recreate the merge commits using the
404404
`recursive` merge strategy; Different merge strategies can be used only via
405405
explicit `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
802804
case" 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+
804939
BUGS
805940
----
806941
The todo list presented by `--preserve-merges --interactive` does not

0 commit comments

Comments
 (0)