Home Explore Blog CI



git

10th chunk of `Documentation/git-rebase.adoc`
e06bb61c91240b02b78aa0c8fd857eac8a36d5748b62fbdd0000000100000fa1

will require more lines of matching context to apply).

The 'merge' backend works with a full copy of each relevant file,
insulating it from these types of problems.

Labelling of conflicts markers
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

When there are content conflicts, the merge machinery tries to
annotate each side's conflict markers with the commits where the
content came from.  Since the 'apply' backend drops the original
information about the rebased commits and their parents (and instead
generates new fake commits based off limited information in the
generated patches), those commits cannot be identified; instead it has
to fall back to a commit summary.  Also, when `merge.conflictStyle` is
set to `diff3` or `zdiff3`, the 'apply' backend will use "constructed merge
base" to label the content from the merge base, and thus provide no
information about the merge base commit whatsoever.

The 'merge' backend works with the full commits on both sides of history
and thus has no such limitations.

Hooks
~~~~~

The 'apply' backend has not traditionally called the post-commit hook,
while the 'merge' backend has.  Both have called the post-checkout hook,
though the 'merge' backend has squelched its output.  Further, both
backends only call the post-checkout hook with the starting point
commit of the rebase, not the intermediate commits nor the final
commit.  In each case, the calling of these hooks was by accident of
implementation rather than by design (both backends were originally
implemented as shell scripts and happened to invoke other commands
like `git checkout` or `git commit` that would call the hooks).  Both
backends should have the same behavior, though it is not entirely
clear which, if any, is correct.  We will likely make rebase stop
calling either of these hooks in the future.

Interruptability
~~~~~~~~~~~~~~~~

The 'apply' backend has safety problems with an ill-timed interrupt; if
the 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 a
subsequent `git rebase --abort`.  The 'merge' backend does not appear to
suffer from the same shortcoming.  (See
https://lore.kernel.org/git/20200207132152.GC2868@szeder.dev/ for
details.)

Commit Rewording
~~~~~~~~~~~~~~~~

When a conflict occurs while rebasing, rebase stops and asks the user
to resolve.  Since the user may need to make notable changes while
resolving conflicts, after conflicts are resolved and the user has run
`git rebase --continue`, the rebase should open an editor and ask the
user to update the commit message.  The 'merge' backend does this, while
the 'apply' backend blindly applies the original commit message.

Miscellaneous differences
~~~~~~~~~~~~~~~~~~~~~~~~~

There are a few more behavioral differences that most folks would
probably consider inconsequential but which are mentioned for
completeness:

* Reflog: The two backends will use different wording when describing
  the changes made in the reflog, though both will make use of the
  word "rebase".

* Progress, informational, and error messages: The two backends
  provide slightly different progress and informational messages.
  Also, the apply backend writes error messages (such as "Your files
  would be overwritten...") to stdout, while the merge backend writes
  them to stderr.

* State directories: The two backends keep their state in different
  directories under `.git/`

include::merge-strategies.adoc[]

NOTES
-----

You should understand the implications of using `git rebase` on a
repository that you share.  See also RECOVERING FROM UPSTREAM REBASE
below.

When the rebase is run, it will first execute a `pre-rebase` hook if one
exists.  You can use this hook to do sanity checks and reject the rebase
if it isn't appropriate.  Please see the template `pre-rebase` hook script
for an example.

Upon completion, `<branch>` will be the current branch.

INTERACTIVE MODE
----------------

Rebasing interactively means that you have a chance

Title: Git Rebase Backend Comparison and Behavioral Differences
Summary
The 'apply' and 'merge' backends of the git rebase command have distinct differences in their behavior, including hook invocation, interruptability, commit rewording, and miscellaneous aspects such as reflog, progress messages, and state directories, highlighting the trade-offs and limitations of each approach, and providing guidance on using git rebase in shared repositories and interactive mode.