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.
- First, the work to do is calculated. This is basically
git rev-list <upstream>..<branch>
to identify all the commits that need to be moved over.- If you are doing a normal (patch-based) rebase, then the patches for each of those commits will be generated and saved in the rebase state folder (
.git/rebase-apply
). - If you invoked rebase with
git rebase --merge
then the commits are stored in a different state folder (.git/rebase-merge
).
- If you are doing a normal (patch-based) rebase, then the patches for each of those commits will be generated and saved in the rebase state folder (
- Next, the
HEAD
is detached and set to theonto
commit (the new base branch, where you will be applying those changes). - Application takes place until a commit cannot be applied.
- If you are doing a patch-based rebase, then patches are applied in order. If a patch fails to apply, then Git will try to instead
cherry-pick
the commit in question. This is becausecherry-pick
is able to write merge conflicts to the index and working directory. - If you are doing a merge-based rebase, then the commit is
cherry-pick
ed.
- If you are doing a patch-based rebase, then patches are applied in order. If a patch fails to apply, then Git will try to instead
- If a
cherry-pick
fails with conflicts, rebase stops and you (the user) must resolve any conflicts andgit add
them to the index. When you have resolved all conflicts, you cangit rebase --continue
. - Once all conflicts have been applied, the original branch is updated to point to the final, rebased commit.
来源:https://stackoverflow.com/questions/38077262/git-rebase-implementation-details