git rebase [-i | --interactive] [<options>] [--exec <cmd>][--onto <newbase> | --keep-base] [<upstream> [<branch>]]git rebase [-i | --interactive] [<options>] [--exec <cmd>] [--onto <newbase>]--root [<branch>]git rebase (--continue|--skip|--abort|--quit|--edit-todo|--show-current-patch)
If<branch> is specified,git
rebase
will perform an automaticgit
switch
<branch> before doing anything else. Otherwiseit remains on the current branch.
If<upstream> is not specified, the upstream configured inbranch.
<name>.remote
andbranch.
<name>.merge
options will be used (seegit-config[1] for details) and the--fork-point
option isassumed. If you are currently not on any branch or if the currentbranch does not have a configured upstream, the rebase will abort.
All changes made by commits in the current branch but that are notin<upstream> are saved to a temporary area. This is the same setof commits that would be shown bygit
log
<upstream>..HEAD
; or bygit
log
fork_point'..HEAD
, if--fork-point
is active (see thedescription on--fork-point
below); or bygit
log
HEAD
, if the--root
option is specified.
The current branch is reset to<upstream> or<newbase> if the--onto
option was supplied. This has the exact same effect asgit
reset
--hard
<upstream> (or<newbase>).ORIG_HEAD
is setto point at the tip of the branch before the reset.
Note | ORIG_HEAD is not guaranteed to still point to the previous branch tipat the end of the rebase if other commands that write that pseudo-ref(e.g.git reset ) are used during the rebase. The previous branch tip,however, is accessible using the reflog of the current branch(i.e.@{1} , seegitrevisions[7]). |
The commits that were previously saved into the temporary area arethen reapplied to the current branch, one by one, in order. Note thatany commits inHEAD
which introduce the same textual changes as a commitinHEAD..
<upstream> are omitted (i.e., a patch already accepted upstreamwith a different commit message or timestamp will be skipped).
It is possible that a merge failure will prevent this process from beingcompletely automatic. You will have to resolve any such merge failureand rungit
rebase
--continue
. Another option is to bypass the committhat caused the merge failure withgit
rebase
--skip
. To check out theoriginal<branch> and remove the.git/rebase-apply
working files, usethe commandgit
rebase
--abort
instead.
Assume the following history exists and the current branch is "topic":
A---B---C topic / D---E---F---G master
From this point, the result of either of the following commands:
git rebase mastergit rebase master topic
would be:
A'--B'--C' topic / D---E---F---G master
NOTE: The latter form is just a short-hand ofgit
checkout
topic
followed bygit
rebase
master
. When rebase exitstopic
willremain the checked-out branch.
If the upstream branch already contains a change you have made (e.g.,because you mailed a patch which was applied upstream), then that commitwill be skipped and warnings will be issued (if themerge backend isused). For example, runninggit
rebase
master
on the followinghistory (in whichA'
andA
introduce the same set of changes, buthave different committer information):
A---B---C topic / D---E---A'---F master
will result in:
B'---C' topic / D---E---A'---F master
Here is how you would transplant a topic branch based on onebranch to another, to pretend that you forked the topic branchfrom the latter branch, usingrebase
--onto
.
First let’s assume yourtopic is based on branchnext.For example, a feature developed intopic depends on somefunctionality which is found innext.
o---o---o---o---o master \ o---o---o---o---o next \ o---o---o topic
We want to maketopic forked from branchmaster; for example,because the functionality on whichtopic depends was merged into themore stablemaster branch. We want our tree to look like this:
o---o---o---o---o master | \ | o'--o'--o' topic \ o---o---o---o---o next
We can get this using the following command:
git rebase --onto master next topic
Another example of --onto option is to rebase part of abranch. If we have the following situation:
H---I---J topicB / E---F---G topicA / A---B---C---D master
then the command
git rebase --onto master topicA topicB
would result in:
H'--I'--J' topicB / | E---F---G topicA |/ A---B---C---D master
This is useful when topicB does not depend on topicA.
A range of commits could also be removed with rebase. If we havethe following situation:
E---F---G---H---I---J topicA
then the command
git rebase --onto topicA~5 topicA~3 topicA
would result in the removal of commits F and G:
E---H'---I'---J' topicA
This is useful if F and G were flawed in some way, or should not bepart of topicA. Note that the argument to--onto
and the<upstream>parameter can be any valid commit-ish.
In case of conflict,git
rebase
will stop at the first problematic commitand leave conflict markers in the tree. You can usegit
diff
to locatethe markers (<<<<<<) and make edits to resolve the conflict. For eachfile you edit, you need to tell Git that the conflict has been resolved,typically this would be done with
git add <filename>
After resolving the conflict manually and updating the index with thedesired resolution, you can continue the rebasing process with
git rebase --continue
Alternatively, you can undo thegit rebase with
git rebase --abort
The options in this section cannot be used with any other option,including not with each other:
Restart the rebasing process after having resolved a merge conflict.
Restart the rebasing process by skipping the current patch.
Abort the rebase operation and reset HEAD to the originalbranch. If<branch> was provided when the rebase operation wasstarted, thenHEAD
will be reset to<branch>. OtherwiseHEAD
will be reset to where it was when the rebase operation wasstarted.
Abort the rebase operation butHEAD
is not reset back to theoriginal branch. The index and working tree are also leftunchanged as a result. If a temporary stash entry was createdusing--autostash
, it will be saved to the stash list.
Edit the todo list during an interactive rebase.
Show the current patch in an interactive rebase or when rebaseis stopped because of conflicts. This is the equivalent ofgit
show
REBASE_HEAD
.
Starting point at which to create the new commits. If the--onto
option is not specified, the starting point is<upstream>. May be any valid commit, and not just anexisting branch name.
As a special case, you may use "A...B" as a shortcut for themerge base of A and B if there is exactly one merge base. You canleave out at most one of A and B, in which case it defaults to HEAD.
Set the starting point at which to create the new commits to themerge base of<upstream> and<branch>. Runninggit
rebase
--keep-base
<upstream><branch> is equivalent torunninggit
rebase
--reapply-cherry-picks
--no-fork-point
--onto
<upstream>...
<branch><upstream><branch>.
This option is useful in the case where one is developing a feature ontop of an upstream branch. While the feature is being worked on, theupstream branch may advance and it may not be the best idea to keeprebasing on top of the upstream but to keep the base commit as-is. Asthe base commit is unchanged this option implies--reapply-cherry-picks
to avoid losing commits.
Although both this option and--fork-point
find the merge base between<upstream> and<branch>, this option uses the merge base as thestartingpoint on which new commits will be created, whereas--fork-point
usesthe merge base to determine theset of commits which will be rebased.
See also INCOMPATIBLE OPTIONS below.
Upstream branch to compare against. May be any valid commit,not just an existing branch name. Defaults to the configuredupstream for the current branch.
Working branch; defaults toHEAD
.
Use applying strategies to rebase (callinggit-am
internally). This option may become a no-op in the futureonce the merge backend handles everything the apply one does.
See also INCOMPATIBLE OPTIONS below.
How to handle commits that are not empty to start and are notclean cherry-picks of any upstream commit, but which becomeempty after rebasing (because they contain a subset of alreadyupstream changes):
drop
The commit will be dropped. This is the default behavior.
keep
The commit will be kept. This option is implied when--exec
isspecified unless-i
/--interactive
is also specified.
stop
ask
The rebase will halt when the commit is applied, allowing you tochoose whether to drop it, edit files more, or just commit the emptychanges. This option is implied when-i
/--interactive
isspecified.ask
is a deprecated synonym ofstop
.
Note that commits which start empty are kept (unless--no-keep-empty
is specified), and commits which are clean cherry-picks (as determinedbygit
log
--cherry-mark
...) are detected and dropped as apreliminary step (unless--reapply-cherry-picks
or--keep-base
ispassed).
See also INCOMPATIBLE OPTIONS below.
Do not keep commits that start empty before the rebase(i.e. that do not change anything from its parent) in theresult. The default is to keep commits which start empty,since creating such commits requires passing the--allow-empty
override flag togit
commit
, signifying that a user is veryintentionally creating such a commit and thus wants to keepit.
Usage of this flag will probably be rare, since you can get rid ofcommits that start empty by just firing up an interactive rebase andremoving the lines corresponding to the commits you don’t want. Thisflag exists as a convenient shortcut, such as for cases where externaltools generate many empty commits and you want them all removed.
For commits which do not start empty but become empty after rebasing,see the--empty
flag.
See also INCOMPATIBLE OPTIONS below.
Reapply all clean cherry-picks of any upstream commit insteadof preemptively dropping them. (If these commits then becomeempty after rebasing, because they contain a subset of alreadyupstream changes, the behavior towards them is controlled bythe--empty
flag.)
In the absence of--keep-base
(or if--no-reapply-cherry-picks
isgiven), these commits will be automatically dropped. Because thisnecessitates reading all upstream commits, this can be expensive inrepositories with a large number of upstream commits that need to beread. When using themerge backend, warnings will be issued for eachdropped commit (unless--quiet
is given). Advice will also be issuedunlessadvice.skippedCherryPicks
is set to false (seegit-config[1]).
--reapply-cherry-picks
allows rebase to forgo reading all upstreamcommits, potentially improving performance.
See also INCOMPATIBLE OPTIONS below.
No-op. Rebasing commits with an empty message used to failand this option would override that behavior, allowing commitswith empty messages to be rebased. Now commits with an emptymessage do not cause rebasing to halt.
See also INCOMPATIBLE OPTIONS below.
Using merging strategies to rebase (default).
Note that a rebase merge works by replaying each commit from the workingbranch on top of the<upstream> branch. Because of this, when a mergeconflict happens, the side reported asours is the so-far rebasedseries, starting with<upstream>, andtheirs is the working branch.In other words, the sides are swapped.
See also INCOMPATIBLE OPTIONS below.
Use the given merge strategy, instead of the defaultort
.This implies--merge
.
Becausegit
rebase
replays each commit from the working branchon top of the<upstream> branch using the given strategy, usingtheours
strategy simply empties all patches from the<branch>,which makes little sense.
See also INCOMPATIBLE OPTIONS below.
Pass the <strategy-option> through to the merge strategy.This implies--merge
and, if no strategy has beenspecified,-s
ort
. Note the reversal ofours andtheirs as noted above for the-m
option.
See also INCOMPATIBLE OPTIONS below.
--rerere-autoupdate
--no-rerere-autoupdate
After the rerere mechanism reuses a recorded resolution onthe current conflict to update the files in the workingtree, allow it to also update the index with the result ofresolution.--no-rerere-autoupdate
is a good way todouble-check whatrerere
did and catch potentialmismerges, before committing the result to the index with aseparategit
add
.
GPG-sign commits. Thekeyid
argument is optional anddefaults to the committer identity; if specified, it must bestuck to the option without a space.--no-gpg-sign
is useful tocountermand bothcommit.gpgSign
configuration variable, andearlier--gpg-sign
.
Be quiet. Implies--no-stat
.
Be verbose. Implies--stat
.
Show a diffstat of what changed upstream since the last rebase. Thediffstat is also controlled by the configuration option rebase.stat.
Do not show a diffstat as part of the rebase process.
This option bypasses the pre-rebase hook. See alsogithooks[5].
Allows the pre-rebase hook to run, which is the default. This option canbe used to override--no-verify
. See alsogithooks[5].
Ensure at least<n> lines of surrounding context match beforeand after each change. When fewer lines of surroundingcontext exist they all must match. By default no context isever ignored. Implies--apply
.
See also INCOMPATIBLE OPTIONS below.
Individually replay all rebased commits instead of fast-forwardingover the unchanged ones. This ensures that the entire history ofthe rebased branch is composed of new commits.
You may find this helpful after reverting a topic branch merge, as this optionrecreates the topic branch with fresh commits so it can be remergedsuccessfully without needing to "revert the reversion" (see therevert-a-faulty-merge How-To fordetails).
Use reflog to find a better common ancestor between<upstream>and<branch> when calculating which commits have beenintroduced by<branch>.
When--fork-point
is active,fork_point will be used instead of<upstream> to calculate the set of commits to rebase, wherefork_point is the result ofgit
merge-base
--fork-point
<upstream><branch> command (seegit-merge-base[1]). Iffork_pointends up being empty, the<upstream> will be used as a fallback.
If<upstream> or--keep-base
is given on the command line, thenthe default is--no-fork-point
, otherwise the default is--fork-point
. See alsorebase.forkpoint
ingit-config[1].
If your branch was based on<upstream> but<upstream> was rewound andyour branch contains commits which were dropped, this option can be usedwith--keep-base
in order to drop those commits from your branch.
See also INCOMPATIBLE OPTIONS below.
Ignore whitespace differences when trying to reconciledifferences. Currently, each backend implements an approximation ofthis behavior:
When applying a patch, ignore changes in whitespace in contextlines. Unfortunately, this means that if the "old" lines beingreplaced by the patch differ only in whitespace from the existingfile, you will get a merge conflict instead of a successful patchapplication.
Treat lines with only whitespace changes as unchanged when merging.Unfortunately, this means that any patch hunks that were intendedto modify whitespace and nothing else will be dropped, even if theother side had no changes that conflicted.
This flag is passed to thegit
apply
program(seegit-apply[1]) that applies the patch.Implies--apply
.
See also INCOMPATIBLE OPTIONS below.
Instead of using the current time as the committer date, usethe author date of the commit being rebased as the committerdate. This option implies--force-rebase
.
Instead of using the author date of the original commit, usethe current time as theauthor date of the rebased commit. Thisoption implies--force-rebase
.
See also INCOMPATIBLE OPTIONS below.
Add aSigned-off-by
trailer to all the rebased commits. Notethat if--interactive
is given then only commits marked to bepicked, edited or reworded will have the trailer added.
See also INCOMPATIBLE OPTIONS below.
Make a list of the commits which are about to be rebased. Let theuser edit that list before rebasing. This mode can also be used tosplit commits (see SPLITTING COMMITS below).
The commit list format can be changed by setting the configuration optionrebase.instructionFormat. A customized instruction format will automaticallyhave the commit hash prepended to the format.
See also INCOMPATIBLE OPTIONS below.
By default, a rebase will simply drop merge commits from the todolist, and put the rebased commits into a single, linear branch.With--rebase-merges
, the rebase will instead try to preservethe branching structure within the commits that are to be rebased,by recreating the merge commits. Any resolved merge conflicts ormanual amendments in these merge commits will have to beresolved/re-applied manually.--no-rebase-merges
can be used tocountermand both therebase.rebaseMerges
config option and a previous--rebase-merges
.
When rebasing merges, there are two modes:rebase-cousins
andno-rebase-cousins
. If the mode is not specified, it defaults tono-rebase-cousins
. Inno-rebase-cousins
mode, commits which do not have<upstream> as direct ancestor will keep their original branch point, i.e.commits that would be excluded bygit-log[1]'s--ancestry-path
option will keep their original ancestry by default. Inrebase-cousins
mode,such commits are instead rebased onto<upstream> (or<onto>, ifspecified).
It is currently only possible to recreate the merge commits using theort
merge strategy; different merge strategies can be used only viaexplicitexec
git
merge
-s
<strategy> [...] commands.
See also REBASING MERGES and INCOMPATIBLE OPTIONS below.
Append "exec <cmd>" after each line creating a commit in thefinal history.<cmd> will be interpreted as one or more shellcommands. Any command that fails will interrupt the rebase,with exit code 1.
You may execute several commands by either using one instance of--exec
with several commands:
git rebase -i --exec "cmd1 && cmd2 && ..."
or by giving more than one--exec
:
git rebase -i --exec "cmd1" --exec "cmd2" --exec ...
If--autosquash
is used,exec
lines will not be appended forthe intermediate commits, and will only appear at the end of eachsquash/fixup series.
This uses the--interactive
machinery internally, but it can be runwithout an explicit--interactive
.
See also INCOMPATIBLE OPTIONS below.
Rebase all commits reachable from<branch>, instead oflimiting them with an<upstream>. This allows you to rebasethe root commit(s) on a branch.
See also INCOMPATIBLE OPTIONS below.
Automatically squash commits with specially formatted messages intoprevious commits being rebased. If a commit message starts with"squash! ", "fixup! " or "amend! ", the remainder of the titleis taken as a commit specifier, which matches a previous commit if itmatches the title or the hash of that commit. If no commitmatches fully, matches of the specifier with the start of committitles are considered.
In the rebase todo list, the actions of squash, fixup and amend commits arechanged frompick
tosquash
,fixup
orfixup
-C
, respectively, and theyare moved right after the commit they modify. The--interactive
option canbe used to review and edit the todo list before proceeding.
The recommended way to create commits with squash markers is by using the--squash
,--fixup
,--fixup=amend:
or--fixup=reword:
options ofgit-commit[1], which take the target commit as an argument andautomatically fill in the title of the new commit from that.
Setting configuration variablerebase.autoSquash
to true enablesauto-squashing by default for interactive rebase. The--no-autosquash
option can be used to override that setting.
See also INCOMPATIBLE OPTIONS below.
Automatically create a temporary stash entry before the operationbegins, and apply it after the operation ends. This meansthat you can run rebase on a dirty worktree. However, usewith care: the final stash application after a successfulrebase might result in non-trivial conflicts.
Automatically rescheduleexec
commands that failed. This only makessense in interactive mode (or when an--exec
option was provided).
This option applies once a rebase is started. It is preserved for the wholerebase based on, in order, the command line option provided to the initialgit
rebase
, therebase.rescheduleFailedExec
configuration (seegit-config[1] or "CONFIGURATION" below), or it defaults to false.
Recording this option for the whole rebase is a convenience feature. Otherwisean explicit--no-reschedule-failed-exec
at the start would be overridden bythe presence of arebase.rescheduleFailedExec=true
configuration whengit
rebase
--continue
is invoked. Currently, you cannot pass--
[no-
]reschedule-failed-exec
togit
rebase
--continue
.
Automatically force-update any branches that point to commits thatare being rebased. Any branches that are checked out in a worktreeare not updated in this way.
If the configuration variablerebase.updateRefs
is set, then this optioncan be used to override and disable this setting.
See also INCOMPATIBLE OPTIONS below.
The following options:
--apply
--whitespace
-C
are incompatible with the following options:
--merge
--strategy
--strategy-option
--autosquash
--rebase-merges
--interactive
--exec
--no-keep-empty
--empty=
--[no-]reapply-cherry-picks when used without --keep-base
--update-refs
--root when used without --onto
In addition, the following pairs of options are incompatible:
--keep-base and --onto
--keep-base and --root
--fork-point and --root
git
rebase
has two primary backends:apply andmerge. (Theapplybackend used to be known as theam backend, but the name led toconfusion as it looks like a verb instead of a noun. Also, themergebackend used to be known as the interactive backend, but it is nowused for non-interactive cases as well. Both were renamed based onlower-level functionality that underpinned each.) There are somesubtle differences in how these two backends behave:
Theapply backend unfortunately drops intentionally empty commits, i.e.commits that started empty, though these are rare in practice. Italso drops commits that become empty and has no option for controllingthis behavior.
Themerge backend keeps intentionally empty commits by default (thoughwith-i
they are marked as empty in the todo list editor, or they canbe dropped automatically with--no-keep-empty
).
Similar to the apply backend, by default the merge backend dropscommits that become empty unless-i
/--interactive
is specified (inwhich case it stops and asks the user what to do). The merge backendalso has an--empty=
(drop
|keep
|stop
) option for changing the behaviorof handling commits that become empty.
Due to the lack of accurate tree information (arising fromconstructing fake ancestors with the limited information available inpatches), directory rename detection is disabled in theapply backend.Disabled directory rename detection means that if one side of historyrenames a directory and the other adds new files to the old directory,then the new files will be left behind in the old directory withoutany warning at the time of rebasing that you may want to move thesefiles into the new directory.
Directory rename detection works with themerge backend to provide youwarnings in such cases.
Theapply backend works by creating a sequence of patches (by callingformat-patch
internally), and then applying the patches in sequence(callingam
internally). Patches are composed of multiple hunks,each with line numbers, a context region, and the actual changes. Theline numbers have to be taken with some offset, since the other sidewill likely have inserted or deleted lines earlier in the file. Thecontext region is meant to help find how to adjust the line numbers inorder to apply the changes to the right lines. However, if multipleareas of the code have the same surrounding lines of context, thewrong one can be picked. There are real-world cases where this hascaused commits to be reapplied incorrectly with no conflicts reported.Settingdiff.context
to a larger value may prevent such types ofproblems, but increases the chance of spurious conflicts (since itwill require more lines of matching context to apply).
Themerge backend works with a full copy of each relevant file,insulating it from these types of problems.
When there are content conflicts, the merge machinery tries toannotate each side’s conflict markers with the commits where thecontent came from. Since theapply backend drops the originalinformation about the rebased commits and their parents (and insteadgenerates new fake commits based off limited information in thegenerated patches), those commits cannot be identified; instead it hasto fall back to a commit summary. Also, whenmerge.conflictStyle
isset todiff3
orzdiff3
, theapply backend will use "constructed mergebase" to label the content from the merge base, and thus provide noinformation about the merge base commit whatsoever.
Themerge backend works with the full commits on both sides of historyand thus has no such limitations.
Theapply backend has not traditionally called the post-commit hook,while themerge backend has. Both have called the post-checkout hook,though themerge backend has squelched its output. Further, bothbackends only call the post-checkout hook with the starting pointcommit of the rebase, not the intermediate commits nor the finalcommit. In each case, the calling of these hooks was by accident ofimplementation rather than by design (both backends were originallyimplemented as shell scripts and happened to invoke other commandslikegit
checkout
orgit
commit
that would call the hooks). Bothbackends should have the same behavior, though it is not entirelyclear which, if any, is correct. We will likely make rebase stopcalling either of these hooks in the future.
Theapply backend has safety problems with an ill-timed interrupt; ifthe user presses Ctrl-C at the wrong time to try to abort the rebase,the rebase can enter a state where it cannot be aborted with asubsequentgit
rebase
--abort
. Themerge backend does not appear tosuffer from the same shortcoming. (Seehttps://lore.kernel.org/git/20200207132152.GC2868@szeder.dev/ fordetails.)
When a conflict occurs while rebasing, rebase stops and asks the userto resolve. Since the user may need to make notable changes whileresolving conflicts, after conflicts are resolved and the user has rungit
rebase
--continue
, the rebase should open an editor and ask theuser to update the commit message. Themerge backend does this, whiletheapply backend blindly applies the original commit message.
There are a few more behavioral differences that most folks wouldprobably consider inconsequential but which are mentioned forcompleteness:
Reflog: The two backends will use different wording when describingthe changes made in the reflog, though both will make use of theword "rebase".
Progress, informational, and error messages: The two backendsprovide slightly different progress and informational messages.Also, the apply backend writes error messages (such as "Your fileswould be overwritten…") to stdout, while the merge backend writesthem to stderr.
State directories: The two backends keep their state in differentdirectories under.git/
The merge mechanism (git
merge
andgit
pull
commands) allows thebackendmerge strategies to be chosen with-s
option. Some strategiescan also take their own options, which can be passed by giving-X
<option>arguments togit
merge
and/orgit
pull
.
ort
This is the default merge strategy when pulling or merging onebranch. This strategy can only resolve two heads using a3-way merge algorithm. When there is more than one commonancestor that can be used for 3-way merge, it creates a mergedtree of the common ancestors and uses that as the referencetree for the 3-way merge. This has been reported to result infewer merge conflicts without causing mismerges by tests doneon actual merge commits taken from Linux 2.6 kerneldevelopment history. Additionally this strategy can detectand handle merges involving renames. It does not make use ofdetected copies. The name for this algorithm is an acronym("Ostensibly Recursive’s Twin") and came from the fact that itwas written as a replacement for the previous defaultalgorithm,recursive
.
In the case where the path is a submodule, if the submodule commit used onone side of the merge is a descendant of the submodule commit used on theother side of the merge, Git attempts to fast-forward to thedescendant. Otherwise, Git will treat this case as a conflict, suggestingas a resolution a submodule commit that is descendant of the conflictingones, if one exists.
Theort
strategy can take the following options:
ours
This option forces conflicting hunks to be auto-resolved cleanly byfavoringour version. Changes from the other tree that do notconflict with our side are reflected in the merge result.For a binary file, the entire contents are taken from our side.
This should not be confused with theours
merge strategy, which does noteven look at what the other tree contains at all. It discards everythingthe other tree did, declaringour history contains all that happened in it.
theirs
This is the opposite ofours
; note that, unlikeours
, there isnotheirs
merge strategy to confuse this merge option with.
ignore-space-change
ignore-all-space
ignore-space-at-eol
ignore-cr-at-eol
Treats lines with the indicated type of whitespace change asunchanged for the sake of a three-way merge. Whitespacechanges mixed with other changes to a line are not ignored.See alsogit-diff[1]-b
,-w
,--ignore-space-at-eol
, and--ignore-cr-at-eol
.
Iftheir version only introduces whitespace changes to a line,our version is used;
Ifour version introduces whitespace changes buttheirversion includes a substantial change,their version is used;
Otherwise, the merge proceeds in the usual way.
renormalize
This runs a virtual check-out and check-in of all three stagesof any file which needs a three-way merge. This option ismeant to be used when merging branches with different cleanfilters or end-of-line normalization rules. See "Mergingbranches with differing checkin/checkout attributes" ingitattributes[5] for details.
no-renormalize
Disables therenormalize
option. This overrides themerge.renormalize
configuration variable.
find-renames
[=
<n>]Turn on rename detection, optionally setting the similaritythreshold. This is the default. This overrides themerge.renames
configuration variable.See alsogit-diff[1]--find-renames
.
rename-threshold=
<n>Deprecated synonym forfind-renames=
<n>.
no-renames
Turn off rename detection. This overrides themerge.renames
configuration variable.See alsogit-diff[1]--no-renames
.
histogram
Deprecated synonym fordiff-algorithm=histogram
.
patience
Deprecated synonym fordiff-algorithm=patience
.
diff-algorithm=
(histogram
|minimal
|myers
|patience
)Use a different diff algorithm while merging, which can helpavoid mismerges that occur due to unimportant matching lines(such as braces from distinct functions). See alsogit-diff[1]--diff-algorithm
. Note thatort
defaults todiff-algorithm=histogram
, while regular diffscurrently default to thediff.algorithm
config setting.
subtree
[=
<path>]This option is a more advanced form ofsubtree strategy, wherethe strategy makes a guess on how two trees must be shifted tomatch with each other when merging. Instead, the specified pathis prefixed (or stripped from the beginning) to make the shape oftwo trees to match.
recursive
This is now a synonym forort
. It was an alternativeimplementation until v2.49.0, but was redirected to meanort
in v2.50.0. The previous recursive strategy was the defaultstrategy for resolving two heads from Git v0.99.9k untilv2.33.0.
resolve
This can only resolve two heads (i.e. the current branchand another branch you pulled from) using a 3-way mergealgorithm. It tries to carefully detect criss-crossmerge ambiguities. It does not handle renames.
octopus
This resolves cases with more than two heads, but refuses to doa complex merge that needs manual resolution. It isprimarily meant to be used for bundling topic branchheads together. This is the default merge strategy whenpulling or merging more than one branch.
ours
This resolves any number of heads, but the resulting tree of themerge is always that of the current branch head, effectivelyignoring all changes from all other branches. It is meant tobe used to supersede old development history of sidebranches. Note that this is different from the-Xours
option totheort
merge strategy.
subtree
This is a modifiedort
strategy. When merging trees A andB, if B corresponds to a subtree of A, B is first adjusted tomatch the tree structure of A, instead of reading the trees atthe same level. This adjustment is also done to the commonancestor tree.
With the strategies that use 3-way merge (including the default,ort
),if a change is made on both branches, but later reverted on one of thebranches, that change will be present in the merged result; some people findthis behavior confusing. It occurs because only the heads and the merge baseare considered when performing a merge, not the individual commits. The mergealgorithm therefore considers the reverted change as no change at all, andsubstitutes the changed version instead.
You should understand the implications of usinggit
rebase
on arepository that you share. See also RECOVERING FROM UPSTREAM REBASEbelow.
When the rebase is run, it will first execute apre-rebase
hook if oneexists. You can use this hook to do sanity checks and reject the rebaseif it isn’t appropriate. Please see the templatepre-rebase
hook scriptfor an example.
Upon completion,<branch> will be the current branch.
Rebasing interactively means that you have a chance to edit the commitswhich are rebased. You can reorder the commits, and you canremove them (weeding out bad or otherwise unwanted patches).
The interactive mode is meant for this type of workflow:
have a wonderful idea
hack on the code
prepare a series for submission
submit
where point 2. consists of several instances of
a) regular use
finish something worthy of a commit
commit
b) independent fixup
realize that something does not work
fix that
commit it
Sometimes the thing fixed in b.2. cannot be amended to the not-quiteperfect commit it fixes, because that commit is buried deeply in apatch series. That is exactly what interactive rebase is for: use itafter plenty of "a"s and "b"s, by rearranging and editingcommits, and squashing multiple commits into one.
Start it with the last commit you want to retain as-is:
git rebase -i <after-this-commit>
An editor will be fired up with all the commits in your current branch(ignoring merge commits), which come after the given commit. You canreorder the commits in this list to your heart’s content, and you canremove them. The list looks more or less like this:
pick deadbee The oneline of this commitpick fa1afe1 The oneline of the next commit...
The oneline descriptions are purely for your pleasure;git rebase willnot look at them but at the commit names ("deadbee" and "fa1afe1" in thisexample), so do not delete or edit the names.
By replacing the command "pick" with the command "edit", you can tellgit
rebase
to stop after applying that commit, so that you can editthe files and/or the commit message, amend the commit, and continuerebasing.
To interrupt the rebase (just like an "edit" command would do, but withoutcherry-picking any commit first), use the "break" command.
If you just want to edit the commit message for a commit, replace thecommand "pick" with the command "reword".
To drop a commit, replace the command "pick" with "drop", or justdelete 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 beattributed to the author of the first commit. The suggested commitmessage for the folded commit is the concatenation of the firstcommit’s message with those identified by "squash" commands, omitting themessages of commits identified by "fixup" commands, unless "fixup -c"is used. In that case the suggested commit message is only the messageof the "fixup -c" commit, and an editor is opened allowing you to editthe message. The contents (patch) of the "fixup -c" commit are stillincorporated into the folded commit. If there is more than one "fixup -c"commit, the message from the final one is used. You can also use"fixup -C" to get the same behavior as "fixup -c" except without openingan editor.
git
rebase
will stop when "pick" has been replaced with "edit" orwhen a command fails due to merge errors. When you are done editingand/or resolving conflicts you can continue withgit
rebase
--continue
.
For example, if you want to reorder the last 5 commits, such that whatwasHEAD~4
becomes the newHEAD
. To achieve that, you would callgit
rebase
like this:
$ git rebase -i HEAD~5
And move the first patch to the end of the list.
You might want to recreate merge commits, e.g. if you have a historylike this:
X \ A---M---B /---o---O---P---Q
Suppose you want to rebase the side branch starting at "A" to "Q". Makesure that the currentHEAD
is "B", and call
$ git rebase -i -r --onto Q O
Reordering and editing commits usually creates untested intermediatesteps. You may want to check that your history editing did not breakanything by running a test, or at least recompiling at intermediatepoints in history by using the "exec" command (shortcut "x"). You maydo so by creating a todo list like this one:
pick deadbee Implement feature XXXfixup f1a5c00 Fix to feature XXXexec makepick c0ffeee The oneline of the next commitedit deadbab The oneline of the commit afterexec cd subdir; make test...
The interactive rebase will stop when a command fails (i.e. exits withnon-0 status) to give you an opportunity to fix the problem. You cancontinue withgit
rebase
--continue
.
The "exec" command launches the command in a shell (the default one, usually/bin/sh), so you can use shell features (like "cd", ">", ";" …). The commandis run from the root of the working tree.
$ git rebase -i --exec "make test"
This command lets you check that intermediate commits are compilable.The todo list becomes like that:
pick 5928aea oneexec make testpick 04d0fda twoexec make testpick ba46169 threeexec make testpick f4593f9 fourexec make test
In interactive mode, you can mark commits with the action "edit". However,this does not necessarily mean thatgit
rebase
expects the result of thisedit to be exactly one commit. Indeed, you can undo the commit, or you canadd other commits. This can be used to split a commit into two:
Start an interactive rebase withgit
rebase
-i
<commit>^
, where<commit> is the commit you want to split. In fact, any commit rangewill do, as long as it contains that commit.
Mark the commit you want to split with the action "edit".
When it comes to editing that commit, executegit
reset
HEAD^
. Theeffect is that theHEAD
is rewound by one, and the index follows suit.However, the working tree stays the same.
Now add the changes to the index that you want to have in the firstcommit. You can usegit
add
(possibly interactively) orgit
gui
(or both) to do that.
Commit the now-current index with whatever commit message is appropriatenow.
Repeat the last two steps until your working tree is clean.
Continue the rebase withgit
rebase
--continue
.
If you are not absolutely sure that the intermediate revisions areconsistent (they compile, pass the testsuite, etc.) you should usegit
stash
to stash away the not-yet-committed changesafter each commit, test, and amend the commit if fixes are necessary.
Rebasing (or any other form of rewriting) a branch that others havebased work on is a bad idea: anyone downstream of it is forced tomanually fix their history. This section explains how to do the fixfrom the downstream’s point of view. The real fix, however, would beto avoid rebasing the upstream in the first place.
To illustrate, suppose you are in a situation where someone develops asubsystem branch, and you are working on atopic that is dependenton thissubsystem. You might end up with a history like thefollowing:
o---o---o---o---o---o---o---o master \ o---o---o---o---o subsystem \ *---*---* topic
Ifsubsystem is rebased againstmaster, the following happens:
o---o---o---o---o---o---o---o master \ \ o---o---o---o---o o'--o'--o'--o'--o' subsystem \ *---*---* topic
If you now continue development as usual, and eventually mergetopictosubsystem, the commits fromsubsystem will remain duplicated forever:
o---o---o---o---o---o---o---o master \ \ o---o---o---o---o o'--o'--o'--o'--o'--M subsystem \ / *---*---*-..........-*--* topic
Such duplicates are generally frowned upon because they clutter uphistory, making it harder to follow. To clean things up, you need totransplant the commits ontopic to the newsubsystem tip, i.e.,rebasetopic. This becomes a ripple effect: anyone downstream fromtopic is forced to rebase too, and so on!
There are two kinds of fixes, discussed in the following subsections:
This happens if thesubsystem rebase was a simple rebase andhad no conflicts.
This happens if thesubsystem rebase had conflicts, or used--interactive
to omit, edit, squash, or fixup commits; orif the upstream used one ofcommit
--amend
,reset
, ora full history rewriting command likefilter-repo
.
Only works if the changes (patch IDs based on the diff contents) onsubsystem are literally the same before and after the rebasesubsystem did.
In that case, the fix is easy becausegit rebase knows to skipchanges that are already present in the new upstream (unless--reapply-cherry-picks
is given). So if you say(assuming you’re ontopic)
$ git rebase subsystem
you will end up with the fixed history
o---o---o---o---o---o---o---o master \ o'--o'--o'--o'--o' subsystem \ *---*---* topic
Things get more complicated if thesubsystem changes do not exactlycorrespond to the ones before the rebase.
Note | While an "easy case recovery" sometimes appears to be successful even in the hard case, it may have unintended consequences. For example, a commit that was removed viagit rebase --interactive will beresurrected! |
The idea is to manually tellgit
rebase
"where the oldsubsystemended and yourtopic began", that is, what the old merge basebetween them was. You will have to find a way to name the last commitof the oldsubsystem, for example:
With thesubsystem reflog: aftergit
fetch
, the old tip ofsubsystem is atsubsystem@{1}
. Subsequent fetches willincrease the number. (Seegit-reflog[1].)
Relative to the tip oftopic: knowing that yourtopic has threecommits, the old tip ofsubsystem must betopic~3
.
You can then transplant the oldsubsystem..topic
to the new tip bysaying (for the reflog case, and assuming you are ontopic already):
$ git rebase --onto subsystem subsystem@{1}
The ripple effect of a "hard case" recovery is especially bad:everyone downstream fromtopic will now have to perform a "hardcase" recovery too!
The interactive rebase command was originally designed to handleindividual patch series. As such, it makes sense to exclude mergecommits from the todo list, as the developer may have merged thethen-currentmaster
while working on the branch, only to rebaseall the commits ontomaster
eventually (skipping the mergecommits).
However, there are legitimate reasons why a developer may want torecreate merge commits: to keep the branch structure (or "committopology") when working on multiple, inter-related branches.
In the following example, the developer works on a topic branch thatrefactors the way buttons are defined, and on another topic branchthat uses that refactoring to implement a "Report a bug" button. Theoutput ofgit
log
--graph
--format=%s
-5
may look like this:
* Merge branch 'report-a-bug'|\| * Add the feedback button* | Merge branch 'refactor-button'|\ \| |/| * Use the Button class for all buttons| * Extract a generic Button class from the DownloadButton one
The developer might want to rebase those commits to a newermaster
while keeping the branch topology, for example when the first topicbranch is expected to be integrated intomaster
much earlier than thesecond one, say, to resolve merge conflicts with changes to theDownloadButton class that made it intomaster
.
This rebase can be performed using the--rebase-merges
option.It will generate a todo list looking like this:
label onto# Branch: refactor-buttonreset ontopick 123456 Extract a generic Button class from the DownloadButton onepick 654321 Use the Button class for all buttonslabel refactor-button# Branch: report-a-bugreset refactor-button # Use the Button class for all buttonspick abcdef Add the feedback buttonlabel report-a-bugreset ontomerge -C a1b2c3 refactor-button # Merge 'refactor-button'merge -C 6f5e4d report-a-bug # Merge 'report-a-bug'
In contrast to a regular interactive rebase, there arelabel
,reset
andmerge
commands in addition topick
ones.
Thelabel
command associates a label with the current HEAD when thatcommand is executed. These labels are created as worktree-local refs(refs/rewritten/
<label>) that will be deleted when the rebasefinishes. That way, rebase operations in multiple worktrees linked tothe same repository do not interfere with one another. If thelabel
command fails, it is rescheduled immediately, with a helpful message howto proceed.
Thereset
command resets the HEAD, index and worktree to the specifiedrevision. It is similar to anexec
git
reset
--hard
<label>, butrefuses to overwrite untracked files. If thereset
command fails, it isrescheduled immediately, with a helpful message how to edit the todo list(this typically happens when areset
command was inserted into the todolist manually and contains a typo).
Themerge
command will merge the specified revision(s) into whateveris HEAD at that time. With-C
<original-commit>, the commit message ofthe specified merge commit will be used. When the-C
is changed toa lower-case-c
, the message will be opened in an editor after asuccessful merge so that the user can edit the message.
If amerge
command fails for any reason other than merge conflicts (i.e.when the merge operation did not even start), it is rescheduled immediately.
By default, themerge
command will use theort
merge strategy forregular merges, andoctopus
for octopus merges. One can specify adefault strategy for all merges using the--strategy
argument wheninvoking rebase, or can override specific merges in the interactivelist of commands by using anexec
command to callgit
merge
explicitly with a--strategy
argument. Note that when callinggit
merge
explicitly like this, you can make use of the fact that thelabels are worktree-local refs (the refrefs/rewritten/onto
wouldcorrespond to the labelonto
, for example) in order to refer to thebranches you want to merge.
Note: the first command (label
onto
) labels the revision onto whichthe commits are rebased; The nameonto
is just a convention, as a nodto the--onto
option.
It is also possible to introduce completely new merge commits from scratchby adding a command of the formmerge
<merge-head>. This form willgenerate a tentative commit message and always open an editor to let theuser edit it. This can be useful e.g. when a topic branch turns out toaddress more than a single concern and wants to be split into two oreven more topic branches. Consider this todo list:
pick 192837 Switch from GNU Makefiles to CMakepick 5a6c7e Document the switch to CMakepick 918273 Fix detection of OpenSSL in CMakepick afbecd http: add support for TLS v1.3pick fdbaec Fix detection of cURL in CMake on Windows
The one commit in this list that is not related to CMake may very wellhave been motivated by working on fixing all those bugs introduced byswitching to CMake, but it addresses a different concern. To split thisbranch into two topic branches, the todo list could be edited like this:
label ontopick afbecd http: add support for TLS v1.3label tlsv1.3reset ontopick 192837 Switch from GNU Makefiles to CMakepick 918273 Fix detection of OpenSSL in CMakepick fdbaec Fix detection of cURL in CMake on Windowspick 5a6c7e Document the switch to CMakelabel cmakereset ontomerge tlsv1.3merge cmake
Everything below this line in this section is selectively includedfrom thegit-config[1] documentation. The content is the sameas what’s found there:
Default backend to use for rebasing. Possible choices areapply ormerge. In the future, if the merge backend gainsall remaining capabilities of the apply backend, this settingmay become unused.
Whether to show a diffstat of what changed upstream since the lastrebase. False by default.
If set to true, enable the--autosquash
option ofgit-rebase[1] by default for interactive mode.This can be overridden with the--no-autosquash
option.
When set to true, automatically create a temporary stash entrybefore the operation begins, and apply it after the operationends. This means that you can run rebase on a dirty worktree.However, use with care: the final stash application after asuccessful rebase might result in non-trivial conflicts.This option can be overridden by the--no-autostash
and--autostash
options ofgit-rebase[1].Defaults to false.
If set to true enable--update-refs
option by default.
If set to "warn", git rebase -i will print a warning if somecommits are removed (e.g. a line was deleted), however therebase will still proceed. If set to "error", it will printthe previous warning and stop the rebase,git rebase--edit-todo can then be used to correct the error. If set to"ignore", no checking is done.To drop a commit without warning or error, use thedrop
command in the todo list.Defaults to "ignore".
A format string, as specified ingit-log[1], to be used for thetodo list during an interactive rebase. The format willautomatically have the commit hash prepended to the format.
If set to true,git
rebase
will use abbreviated command names in thetodo list resulting in something like this:
p deadbee The oneline of the commitp fa1afe1 The oneline of the next commit...
instead of:
pick deadbee The oneline of the commitpick fa1afe1 The oneline of the next commit...
Defaults to false.
Automatically rescheduleexec
commands that failed. This only makessense in interactive mode (or when an--exec
option was provided).This is the same as specifying the--reschedule-failed-exec
option.
If set to false set--no-fork-point
option by default.
Whether and how to set the--rebase-merges
option by default. Canberebase-cousins
,no-rebase-cousins
, or a boolean. Setting totrue or tono-rebase-cousins
is equivalent to--rebase-merges=no-rebase-cousins
, setting torebase-cousins
isequivalent to--rebase-merges=rebase-cousins
, and setting to false isequivalent to--no-rebase-merges
. Passing--rebase-merges
on thecommand line, with or without an argument, overrides anyrebase.rebaseMerges
configuration.
When generating label names from commit subjects, truncate the names tothis length. By default, the names are truncated to a little less thanNAME_MAX
(to allow e.g..lock
files to be written for thecorresponding loose refs).
Text editor used bygit
rebase
-i
for editing the rebase instruction file.The value is meant to be interpreted by the shell when it is used.It can be overridden by theGIT_SEQUENCE_EDITOR
environment variable.When not configured, the default commit message editor is used instead.
Part of thegit[1] suite