Git Rebasing

From NovaOrdis Knowledge Base
Revision as of 23:33, 18 February 2020 by Ovidiu (talk | contribs) (→‎Overview)
Jump to navigation Jump to search

External

Internal

Overview

Rebasing is one of the two main ways to integrate changes from a branch into another. The other way is merging.

Rebasing works as follows: the operation goes to the common ancestor of the head branch (the branch you are on) and base branch (the branch you're rebasing into), getting the diff introduced by each head branch commit, saving these diffs into temporary files, resetting the head branch to the same commit as the base branch, and the finally applying each change in turn. Intuitively, is equivalent with shifting and morphing each commit of the head branch, after the common ancestor, in top of the base branch.

Merging two branches as described above is the main use case for the rebase. However, rebase can also be used when only one line of development (branch) is involved, to modify, delete or coalesce several logically-related commits into one commit (squash).


, or when two connected branches are involved, to shift head branch commits relative to the base branch commits. This last situation is useful when we intend to merge the branches and we want to avoid a merge commit - the base branch can simply be fast forwarded with the commits from the head branch.

Rebasing rewrites history, by removing the commits that are being rebased and creating new, equivalent ones.

GitRebase.png

Rewriting History

Rebasing removes the commits that are being rebased and creating new, equivalent ones.

Practical Use Cases

Squashing Commits

Squashing Commits

Applying Extra Changes to the Last Commit

Applying Extra Changes to the Last Commit

Shifting Head Branch Commits at the HEAD of the Base Branch

One might to "shift" the head branch in preparation of a merge of the head branch into the base brach. The result of the operation is that all commits applied on the head branch are shifted at the top of the base branch - a side effect is that the commits are modified in the process (the history is rewritten). The advantage of doing that is that when the merge occurs, is a simple fast forward merge, and no additional merge commit is created - the changes required by the merge are already worked into the commits that are rebased.

GitRebaseMerge.png

TODO: research. Before doing that, don't we want to pull --rebase the base branch?

git checkout <head-branch> 
git rebase <base-branch> 

At the end of this step, the branches still exist, but now the head branch can be merged into the base brach by fast forwarding it - a merge commit is not required.

To merge, we just simply fast forward:

git checkout <base-branch>
git merge <head-branch>
GitRebaseMerge2.png

Reordering Commits

The order of commits on a branch can be changed by initiating an interactive rebase, and reordering the commits with the help of the editor.

To Link To

Fixing a Merge Broken by Base Branch Rebase

Update the Commit Message of a Specific Commit

Update the Commit Message of a Specific Commit

Moving a Branch Forward

You are working on a feature branch, named "A", created when the "develop" branch HEAD was commit "ef5". You committed work on the "A" branch, and your commit is "3ba". After a while, you want to apply your changes on the HEAD of "develop", since "develop" has evolved and you want to try

On branch task/of/PLAT-15252
Your branch and 'origin/task/of/PLAT-15252' have diverged,
and have 164 and 1 different commits each, respectively.
  (use "git pull" to merge the remote branch into yours)

Rebasing at the HEAD of the Base Branch

This procedure takes all commits from the head branch that diverged from the base branch, squashes them into one, and applies to the HEAD of the base branch.

You will be given the chance to squash extraneous commits. Change "pick" into "s" for the commits you want squashed into the previous (above) commits.

You will then be given the chance to edit comments.

If you don't want to squash, you can omit -i.
On branch topic/...
Your branch and 'origin/topic/...' have diverged,
and have 1 and 2 different commits each, respectively.
  (use "git pull" to merge the remote branch into yours)
git push --force

You can delete the branch (locally and remotely)

TODO