Git rebase solves the same problem as git merge. Both git merge and rebase are used to integrate changes from one branch into another branch – they just do it in different ways; and it’s important to know the difference.
Imagine you have a project and you’re working on it with a few friends. You all make changes to the project and save your changes in something called a “branch.” A branch is like a separate copy of the project that you can work on without affecting the main project. When you’re done making changes to your branch, you can ask Git to “merge” your changes back into the main project. Git will take all of the changes you made in your branch and add them to the main project, making it easy for everyone to see and use your changes.
Rebasing is a way to merge changes from one branch into another, but it’s a little different from the regular merge process. When you rebase, Git will take all of the changes you made in your branch and apply them one by one to the main project, as if you had made the changes directly to the main project. This can make it easier to see what changes you made and how they fit into the main project.
Let’s think of a scenario.
Our master branch (m) have commit: 1 -> 2 -> 3. Now we need to develop a feature. So we created our own feature branch (f) from the master branch with the latest commit no: 3. We are working on our feature and pushed 3 commits no: 5, 7 and 9. In the meantime; master branch remains busy and commit 4, 6 and 8 was pushed by our amazing team members.
Now at some point; we might need to do 2 things:
- Your feature development is finished and you need to push your work (commit 5,7 & 9) of feature branch (f) to master branch (f);
- Bring the things that has been pushed to master branch (m) (commit 4,6 & 8) into your own branch (f), and then continue to work on the branch (f).
Consider the first scenario. And let’s consider ‘merge’ route. That is we go to master branch and merge the feature branch with the master with the commands –
git checkout master git merge feature
By merging feature into master, master obtains a new commit — a ‘merge commit’. This commit contains everything from our commit – (5+7+9) – into a combined sort of commit (10*) and it appends itself after commit 8 on master.
Now let’s consider the second scenario. And this time we will go with ‘rebase’ route. We will bring all the magical commits pushed into master (m) into our branch (f). Keep in mind; the current commit history for our branch is: 1-> 2-> 3-> 5-> 7-> 9. Now we rebase with master with the following command –
git checkout feature git rebase master
Now this part is interesting. Rebase moves the base of our branch. The process is this –
- First it brings all the commits from master (1-> 2-> 3-> 4-> 6-> 8)
- And applies our commits (5-> 7-> 9); after this base commit 8; one by one to create (5′ -> 7′ -> 9′)
So the new history for our branch (f) becomes – 1-> 2-> 3-> 4-> 6-> 8 -> 5′-> 7′-> 9′. It does not create a new all-in-one sorts of commit; rather it rewrites the history of the branch. Note that; commit 5,7,9 is same as 5′,7’9′ to us but git treats them as new commits (with new SHA’s).
Now here comes the tricky part.
Say our good friend Rafi is working on the same feature. He checked out the feature branch after we pushed the commit 5; and he has committed 10 & 11. So; his commit history looks like this –
1-> 2-> 3-> 5-> 10 -> 11.
In the meantime; we changed the history of feature branch to –
1-> 2-> 3-> 4-> 6-> 8 -> 5′-> 7′-> 9′.
Now whether Rafi wants to bring back master branch commit into his own copy of feature branch; update his copy of feature branch with our feature branch or push his commit into the master branch; there is potential for some conflict and issues; and all because git rebase rewrote the history of the feature branch unlike merge.
So; golden rule of thumb of using rebase is –
don’t rebase a branch unless you are the only one who are using it.
If we want to control and alter commits as they are moved to the new branch while rebasing; we can use Interactive Rebasing. The command for this is –
git checkout feature git rebase -i master
This will open a text editor listing all of the commits that are about to be moved. Here the listing defines what the branch will look like after the rebase is performed. By changing the pick command and/or re-ordering the entries, we can make the branch’s history look like whatever we want.
For example, if the 2nd commit fixes a small problem in the 1st commit, we can condense them into a single commit with the fixup command. Eliminating insignificant commits like this makes feature’s history much easier to understand. This is a benefit of rebase that git merge simply cannot do.
One advantage of using
git merge is that it’s easy to understand and use. It’s a simple way to combine changes from multiple branches, and it’s especially useful when you want to bring all of the changes from one branch into another without any special treatment.
git merge can sometimes create “merge conflicts,” which occur when the same lines of code have been changed in both branches. In this case, Git will ask you to resolve the conflict manually by deciding which changes to keep and which to discard. This can be time-consuming and may require some technical knowledge to resolve.
When you use
git rebase, Git will apply the changes from the branch you want to merge one by one, as if you had made them directly to the branch you’re currently on. This can make it easier to see how the changes fit into the project, and it can also help you avoid merge conflicts.
One advantage of using
git rebase is that it can help you avoid merge conflicts, since the changes are applied one by one. This can make it easier to see how the changes fit into the project and resolve any conflicts that may arise.
git rebase can be more complex to use than
git merge, and it’s generally not recommended for beginners. It can also be more difficult to understand the history of your project when using
git rebase, since the commits are reordered and combined into new ones.
Pros of merge –
- Simple and familiar
- Preserves complete history and chronological order
- Maintains the context of the branch
- Makes it easy to bring changes from one branch into another
- Maintains a clear history of your project, with separate commits for each change
Cons of merge –
- Commit history can become polluted by lots of merge commits
- Debugging using git bisect can become harder
- Can create merge conflicts, which can be time-consuming and difficult to resolve
- May result in a cluttered commit history if you merge branches frequently
Pros of Rebase –
- Streamlines a potentially complex history
- Manipulating a single commit is easy
- Avoids merge commit “noise” in busy repository with busy branches
- Cleans intermediate commits by condensing them into a single commit
- Can help you avoid merge conflicts by applying changes one by one
- Makes it easier to see how changes fit into the project
Cons of rebase –
- Squashing the feature down to a handful of commits can hide many important details.
- Rebasing public repositories can be dangerous when working as a team.
- It’s more work using rebase to keep our feature branch updated always.
- Rebasing with remote branches sometimes requires force push which may cause problems if not done properly.
- More complex to use than
- Can be confusing for beginners
- Can make it harder to understand the history of your project, since commits are reordered and combined into new ones
- If you rebase a branch that has already been pushed to a remote repository, it can cause problems for other collaborators who have based their work on the original commits.
Git Merge and Rebase: Summary
Create a feature branch and then –
- ALWAYS rebase from master to the branch. (merge is fine too)
- And merge from the branch back to master. (avoid rebasing).