Open dorawyy opened 6 years ago
# 2
git checkout mt5
git commit test26_merge_test -m "mt5: x=1"
# 3
git checkout mt6
git commit test26_merge_test -m "mt6: x=2"
# 4
git checkout mt5
git commit test26_merge_test -m "mt5: x=2, y=1"
# 5
git checkout mt6
git commit test26_merge_test -m "mt6: x=3, z=2"
# 6
git checkout mt5
git commit test26_merge_test -m "mt5: x=3, z=2"
git checkout mt5
git rebase mt6
Replay commit2
on top of commit5
failed, due to conflict, requires manually resolution:
Resolve the conflict when reapplying commit2
, continue rebase
Then, meeting the second conflict:
Resolve the conflict when reapplying commit4
(same it exactly the same as commit6
, continue rebase:
As the last commit changes are the same, the previsous commit6
is omitted.
-p
/ --preserve-merges
git checkout mt5
git rebase --preserve-merges mt6
commit2
, conflictResolve the conflict when applying commit2
to head
:
Then, keep rebasing, generates a commit, here is the commit message:
Here is the project tree after rebasing commit2
with -p
param:
commit4
, meeting conflict again:Resolve the conflict, then continue rebasing:
commit6
, the previous cherry-picking commit commit6
, now becomes an empty-commit (compared with head
)
Rebase asks the developer to commit commit6
or not?
If still commit, (git commit --allow-empty
), then a commit is created:
The commit is empty, with no change inside:
#2
git checkout mt8
git commit test26_merge_test -m "mt8:x=2,y=1"
#3
git checkout mt8
git commit test26_merge_test -m "mt8:x=3,z=2"
Project tree becomes:
git checkout mt8
git rebase mt9
Nothing changed, as mt8
is already up-to-date
--force-rebase
git checkout mt8
git rebase mt9 --force-rebase
The rebase process is forced to executed on mt8
(SHA changed):
--force-rebase
& --preserve-merges
git checkout mt8
git rebase mt9 --force-rebase --preserve-merges
Commit on mt8
are rebased, but no visible changes on mt8
.
--preserve-merges
git checkout mt8
git rebase mt9 --preserve-merges
Notified as rebasing finished, no visible changes.
git checkout mt11
git rebase mt12
--preserve-merges
git checkout mt11
git rebase mt12 --preserve-merges
To test
git rebase
parameter optionsgit rebase
testcases scratches--> #76References
git-rebase documentation
Synopsis
--keep-empty
Keep the commits that do not change anything from its parents in the result.
--skip
Restart the rebasing process by skipping the current patch.
--edit-todo
Edit the todo list during an interactive rebase.
-m
/--merge
Use merging strategies to rebase. When the recursive (default) merge strategy is used, this allows rebase to be aware of renames on the upstream side.
Note that a rebase merge works by replaying each commit from the working branch on top of the
<upstream>
branch. Because of this, when a merge conflict happens, the side reported asours
is the so-far rebased series, starting with<upstream>
, and theirs is the working branch. In other words, the sides are swapped.-s <strategy>
/--strategy=<strategy>
Use the given merge strategy. If there is no -s option git merge-recursive is used instead. This implies
--merge
.Because git rebase replays each commit from the working branch on top of the
<upstream>
branch using the given strategy, using theours
strategy simply discards all patches from the<branch>
, which makes little sense.-X <strategy-option>
/--strategy-option=<strategy-option>
Pass the
<strategy-option>
through to the merge strategy. This implies--merge
and, if no strategy has been specified,-s recursive
. Note the reversal of ours and theirs as noted above for the-m
option.-C<n>
Ensure at least
<n>
lines of surrounding context match before and after each change. When fewer lines of surrounding context exist they all must match. By default no context is ever ignored.-f
/--force-rebase
Force a rebase even if the current branch is up to date and the command without
--force
would return without doing anything.You may find this (or
--no-ff
with an interactive rebase) helpful after reverting a topic branch merge, as this option recreates the topic branch with fresh commits so it can be remerged successfully without needing to "revert the reversion".-i
/--interactive
Make a list of the commits which are about to be rebased. Let the user edit that list before rebasing. This mode can also be used to split commits.
The commit list format can be changed by setting the configuration option rebase.instructionFormat. A customized instruction format will automatically have the long commit hash prepended to the format.
-p
/--preserve-merges
Recreate merge commits instead of flattening the history by replaying commits a merge commit introduces. Merge conflict resolutions or manual amendments to merge commits are not preserved.
This uses the
--interactive
machinery internally, but combining it with the--interactive
option explicitly is generally not a good idea unless you know what you are doing. Ref: Differences between default merge andmerge-preserving merge
-x <cmd>
/--exec <cmd>
Append "exec" after each line creating a commit in the final history. will be interpreted as one or more shell commands. Generally, use together with
-i
--root
Rebase all commits reachable from
<branch>
, instead of limiting them with an<upstream>
. This allows you to rebase the root commit(s) on a branch. When used with--onto
, it will skip changes already contained in<newbase>
(instead of<upstream>
) whereas without--onto
it will operate on every change. When used together with both--onto
and--preserve-merges
, all root commits will be rewritten to have<newbase>
as parent instead. If not--onto
branch is specified,--root
will root back the second commit of the repo (the one following the initial commit)--autosquash
&--no-autosquash
When the commit log message begins with "squash! …" (or "fixup! …"), and there is already a commit in the todo list that matches the same
...
, automatically modify the todo list of rebase -i so that the commit marked for squashing comes right after the commit to be modified, and change the action of the moved commit frompick
tosquash
(orfixup
). A commit matches the...
if the commit subject matches, or if the...
refers to the commit’s hash. As a fall-back, partial matches of the commit subject work, too. The recommended way to create fixup/squash commits is by using the--fixup
/--squash
options ofgit-commit
.This option is only valid when the
--interactive
option is used.--autostash
&--no-autostash
Automatically create a temporary stash entry before the operation begins, and apply it after the operation ends. This means that you can run rebase on a dirty worktree. However, use with care: the final stash application after a successful rebase might result in non-trivial conflicts.
--no-ff
With
--interactive
, cherry-pick all rebased commits instead of fast-forwarding over the unchanged ones. This ensures that the entire history of the rebased branch is composed of new commits.Without
--interactive
, this is a synonym for--force-rebase
.You may find this helpful after reverting a topic branch merge, as this option recreates the topic branch with fresh commits so it can be remerged successfully without needing to "revert the reversion".
Tools/command to use
git log branch1..branch2
: list all commits on branch2 after the last common commit of branch1 and branch2git rebase
Interactive modeRebasing interactively means that you have a chance to edit the commits which are rebased. You can reorder the commits, and you can remove them (weeding out bad or otherwise unwanted patches). The interactive mode is meant for this type of workflow:
where point 2. consists of several instances of
a) regular use
Sometimes the thing fixed in b.2. cannot be amended to the not-quite perfect commit it fixes, because that commit is buried deeply in a patch series. That is exactly what interactive rebase is for: use it after plenty of "a"s and "b"s, by rearranging and editing commits, and squashing multiple commits into one.
Start it with the last commit you want to retain as-is:
An editor will be fired up with all the commits in your current branch (ignoring merge commits), which come after the given commit. You can reorder the commits in this list to your heart’s content, and you can remove them. The list looks more or less like this:
The oneline descriptions are purely for your pleasure; git rebase will not look at them but at the commit names ("deadbee" and "fa1afe1" in this example), so do not delete or edit the names.
By replacing the command "pick" with the command "edit", you can tell
git rebase
to stop after applying that commit, so that you can edit the files and/or the commit message, amend the commit, and continue rebasing.If you just want to edit the commit message for a commit, replace the command "pick" with the command "reword".
To drop a commit, replace the command "pick" with "drop", or just delete the matching line.
If you want to fold two or more commits into one, replace the command "pick" for the second and subsequent commits with "squash" or "fixup". If the commits had different authors, the folded commit will be attributed to the author of the first commit. The suggested commit message for the folded commit is the concatenation of the commit messages of the first commit and of those with the "squash" command, but omits the commit messages of commits with the "fixup" command.
git rebase
will stop when "pick" has been replaced with "edit" or when a command fails due to merge errors. When you are done editing and/or resolving conflicts you can continue withgit rebase --continue
.For example, if you want to reorder the last 5 commits, such that what was HEAD~4 becomes the new
HEAD
. To achieve that, you would callgit rebase
like this:And move the first patch to the end of the list. You might want to preserve merges, if you have a history like this:
Suppose you want to rebase the side branch starting at "A" to "Q". Make sure that the current HEAD is "B", and call
Reordering and editing commits usually creates untested intermediate steps. You may want to check that your history editing did not break anything by running a test, or at least recompiling at intermediate points in history by using the "exec" command (shortcut "x"). You may do so by creating a todo list like this one:
git rebase
interactive mode options