Merge and Rebase
When working with branches in Git, you often need to integrate changes from one branch into another. The two most common methods are merge and rebase.
Both combine the work of different branches but they do it differently.
Git Merge
git merge combines the history of two branches by creating a merge commit.
Basic command
git merge branch-nameExample:
git checkout main
git merge feature-loginThis merges the changes from feature-login into main.
You merge into the branch you are currently on.
Fast-Forward Merge
A Fast-Forward merge happens when the target branch has no new commits since the feature branch was created. In this case, Git does not create a merge commit. Instead, it simply moves the branch pointer forward to the latest commit.
This keeps the project history linear and clean.
git merge --ff-only feature-loginTo force the Fast Forward merge u can use git merge --ff-only feature-login
but if there’s a changes in the main (New commits), git will throw an error
Squash Merge
A squash merge combines all commits from a branch into one single commit before merging. And the commits will not appear in the main branch
git merge --squash feature-loginGit Rebase
git rebase is used to integrate changes from one branch into another by reapplying commits on top of a new base commit. Unlike git merge, which creates a merge commit, rebase rewrites the commit history to keep it linear.
The most common cases are simple rebase, rebase with conflicts, and interactive rebase.
Basic command
git rebase branch-nameExample:
# you shloud be in the branch feature-login
git checkout feature-login
git rebase feature-loginWhen you rebase a branch, Git takes the commits from your current branch and put them on top of the main.
Simple Rebase
This is the most common case. The commits of the current branch are reapplied on top of another branch.
Or you can rebase from main:
Rebase With Conflicts
If the same lines of code are changed in both branches, a conflict happens during the rebase.
- function ( a ,b ) {
- const a;
- const b;
- const result = a + b;
- return result
- }
+ function( a, b) {
+ return a + b
+ }Git will show something like:
CONFLICT (content): Merge conflict in function.jsTo resolve it:
# Fix the conflict in the files
<<<<<<< HEAD (current Change)
const a;
const b;
const result = a + b;
return result
=======
return a + b
>>>>>>> Commit id: 5200b20 (Incoming changes)# Add the resolved files
git add file.txt
# Continue the rebase
git rebase --continueOther useful commands:
# if you want to cancel the rebase use `--abort`
git rebase --abort
# if you want to skip the conflict commit and delete it, and continue the rebase use `--skip`
git rebase --skipInteractive Rebase
Interactive rebase lets you edit the commits while rebasing.
git checkout feature
git rebase -i main$ git rebase -i main
pick f051d68 add feature commit
#
# Rebase ba79301..f051d68 onto ba79301 (1 command)
#
# Commands:
# p, pick <commit> = use commit
# r, reword <commit> = use commit, but edit the commit message
# e, edit <commit> = use commit, but stop for amending
# s, squash <commit> = use commit, but meld into previous commit
# f, fixup [-C | -c] <commit> = like "squash" but keep only the previous
...
--INSERT--This does the same rebase, but Git opens an editor so you can:
- reorder commits
- squash commits
- edit commits
- remove commits
- change commit messages
Rebase -i commands
In practice, developers mostly use these:
| Command | Short | Description |
|---|---|---|
| p | Keep the commit as it is |
| r | Keep the commit but edit the commit message |
| e | Pause the rebase to modify the commit |
| s | Combine the commit with the previous commit and edit the message |
| f | Combine the commit with the previous commit and discard its message |
| x | Run a shell command during the rebase |
| d | Remove the commit completely |
| b | Stop the rebase temporarily |
| l | Label the current commit (used for advanced rebases) |
| t | Reset HEAD to a label |
| m | Create a merge commit during rebase |