@@ -403,6 +403,8 @@ reordered, inserted and dropped at will.
403
403
It is currently only possible to recreate the merge commits using the
404
404
`recursive` merge strategy; Different merge strategies can be used only via
405
405
explicit `exec git merge -s <strategy> [...]` commands.
406
+ +
407
+ See also REBASING MERGES below.
406
408
407
409
-p::
408
410
--preserve-merges::
@@ -801,6 +803,139 @@ The ripple effect of a "hard case" recovery is especially bad:
801
803
'everyone' downstream from 'topic' will now have to perform a "hard
802
804
case" recovery too!
803
805
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
+
804
939
BUGS
805
940
----
806
941
The todo list presented by `--preserve-merges --interactive` does not
0 commit comments