I am trying to figure out the working mechanism of git-rebase
. Documentation provides information about what git-rebase
does, but doesn't comment on how it does?
I have looked into the source code, worked out some test cases and so far understand following:
1. Git maintains the state of rebase in .git/rebase-apply
(with files like patch, final-commit, head-name etc)
2. Git uses git-format-patch
to create all necessary patch files (which are inside rebase-apply)
3. Git uses git-am
to apply those patches one by one
I think I am missing quite a lot of details. Where can I find the implementation details? Is it simply dumping the patch and naively applying it?
Your summary is basically complete. Rebase is actually relatively simple.
git rev-list <upstream>..<branch>
to identify all the commits that need to be moved over..git
directory. There are two primary rebase backends, which each use a different folder:
.git/rebase-apply
.git/rebase-merge
HEAD
is detached and set to the onto
commit (the new base branch, where you will be applying those changes).cherry-pick
the commit in question. This is because cherry-pick
is able to write merge conflicts to the index and working directory.cherry-pick
ed.cherry-pick
fails with conflicts, rebase stops and you (the user) must resolve any conflicts and git add
them to the index. When you have resolved all conflicts, you can git rebase --continue
.Some closing details on backends:
The merge backend was originally just the interactive rebase backend. It can be invoked manually with the --merge
option, and is also used as the default backend for --onto
among others. The apply backend is older, and may eventually be replaced entirely by the merge backend.