The Power of Rebasing Before Merging


When using Git, understanding how to rebase our feature branch onto a target branch before merging is a must, particularly in teams that prefer to maintain a linear commit history. Let's explore the common situations we might encounter when using the git rebase
command.
Rebasing is like saying: "Take all the work I did on my feature branch, pretend I started it today based on the latest version of the main code, and put my changes on top of that." It cleans up the history by making it look like development happened sequentially, even when it didn't.
As the first step, we will clone a GitHub repository by running the commands:
git clone <MY_REPO_URL>
cd <MY_REPO_DIR>
Before creating any text files, run the following command to set
UTF-8
as the default encoding (PowerShell):
$PSDefaultParameterValues['Out-File:Encoding'] = 'utf8'
No Conflicts
In this scenario, we will add changes to the main
and feature
branches that will not cause conflicts during the rebase. Add a file in the main
branch:
echo "Line 1 from main" > file.txt
git add file.txt
git commit -m "Commit 1 from main"
git push origin main
Create the feature
branch from the main
branch:
git checkout -b feature
Go back to the main
branch and add a second file:
git checkout main
echo "Line 1 from main" > another_file.txt
git add another_file.txt
git commit -m "Commit 2 from main"
git push origin main
Modify the file.txt
file in the feature
branch:
git checkout feature
echo "Line 2 from feature" >> file.txt
git add file.txt
git commit -m "Commit 1 from feature"
Run git log --oneline --graph --all
to see the current commit history:
* d956da2 (HEAD -> feature) Commit 1 from feature
| * 7e59e9b (origin/main, origin/HEAD, main) Commit 2 from main
|/
* a282a9d Commit 1 from main
* e315dd5 Initial commit
Always pull the latest remote changes with
git fetch origin
before rebasing.
Rebase the feature
branch:
git rebase origin/main
As a result, the rebase is executed successfully. Finally, push the rebased branch:
git push origin feature --force-with-lease
To simulate a pull request, run:
git checkout main
git merge feature
git push origin main
Check the commit history:
* caa0728 (HEAD -> main, origin/main, origin/feature, origin/HEAD, feature) Commit 1 from feature
* 7e59e9b Commit 2 from main
* a282a9d Commit 1 from main
* e315dd5 Initial commit
Modify Conflict
In this second scenario, we will update the same file in both branches. Go back to the main
branch and modify the file.txt
file:
git checkout main
echo "Line 2 from main" >> file.txt
git add file.txt
git commit -m "Commit 3 from main"
git push origin main
Modify the file.txt
file in the feature
branch:
git checkout feature
echo "Line 3 from feature" >> file.txt
git add file.txt
git commit -m "Commit 2 from feature"
See the current commit history:
* 7083f03 (HEAD -> feature) Commit 2 from feature
| * 0825d7e (origin/main, origin/HEAD, main) Commit 3 from main
|/
* caa0728 (origin/feature) Commit 1 from feature
* 7e59e9b Commit 2 from main
* a282a9d Commit 1 from main
* e315dd5 Initial commit
Rebase the feature
branch by running git rebase origin/main
:
Auto-merging file.txt
CONFLICT (content): Merge conflict in file.txt
error: could not apply 7083f03... Commit 2 from feature
hint: Resolve all conflicts manually, mark them as resolved with
hint: "git add/rm <conflicted_files>", then run "git rebase --continue".
hint: You can instead skip this commit: run "git rebase --skip".
hint: To abort and get back to the state before "git rebase", run "git rebase --abort".
Could not apply 7083f03... Commit 2 from feature
Open the file.txt
file in your favorite editor:
Line 1 from main
Line 2 from feature
<<<<<<< HEAD
Line 2 from main
=======
Line 3 from feature
>>>>>>> 7083f03 (Commit 2 from feature)
To resolve the conflict, in this case, we will keep the feature branch change:
Line 1 from main
Line 2 from feature
Line 3 from feature
Save the file and run git add file.txt
. Since this is the only conflict, we can continue with the rebase by running git rebase --continue
. This will open a text editor where we can update the commit message based on the changes we have made. Save and close the editor by pressing ESC
, then typing :wq
, and pressing ENTER
. Push the rebased branch:
git push origin feature --force-with-lease
Let’s simulate a pull request:
git checkout main
git merge feature
git push origin main
Check the commit history:
* 2c5e5d5 (HEAD -> main, origin/main, origin/feature, origin/HEAD, feature) Commit 2 from feature
* 0825d7e Commit 3 from main
* caa0728 Commit 1 from feature
* 7e59e9b Commit 2 from main
* a282a9d Commit 1 from main
* e315dd5 Initial commit
Delete Conflict
In the final scenario, we will update a file in one branch and delete it in the other. Go back to the main
branch and delete the another_file.txt
file:
git checkout main
rm another_file.txt
git rm another_file.txt
git commit -m "Commit 4 from main"
git push origin main
The
rm
command is not need . The commandgit rm
is is sufficient on its own, as it removes the file from the working directory and stages the deletion.
Modify the another_file.txt
file in the feature
branch:
git checkout feature
echo "Line 3 from feature" >> another_file.txt
git add another_file.txt
git commit -m "Commit 3 from feature"
See the current commit history:
* 9cc564d (HEAD -> feature) Commit 3 from feature
| * f7bf8a3 (origin/main, origin/HEAD, main) Commit 4 from main
|/
* 2c5e5d5 (origin/feature) Commit 2 from feature
* 0825d7e Commit 3 from main
* caa0728 Commit 1 from feature
* 7e59e9b Commit 2 from main
* a282a9d Commit 1 from main
* e315dd5 Initial commit
Rebase the feature
branch by running git rebase origin/main
:
CONFLICT (modify/delete): another_file.txt deleted in HEAD and modified in 9cc564d (Commit 3 from feature). Version 9cc564d (Commit 3 from feature) of another_file.txt left in tree.
error: could not apply 9cc564d... Commit 3 from feature
hint: Resolve all conflicts manually, mark them as resolved with
hint: "git add/rm <conflicted_files>", then run "git rebase --continue".
hint: You can instead skip this commit: run "git rebase --skip".
hint: To abort and get back to the state before "git rebase", run "git rebase --abort".
Could not apply 9cc564d... Commit 3 from feature
Resolve the conflict, in this case by deleting the file:
rm another_file.txt
git rm another_file.txt
Continue the rebase by running git rebase --continue
. Then push the rebased branch by running git push origin feature --force-with-lease
. Check the commit history:
* f7bf8a3 (HEAD -> feature, origin/main, origin/feature, origin/HEAD, main) Commit 4 from main
* 2c5e5d5 Commit 2 from feature
* 0825d7e Commit 3 from main
* caa0728 Commit 1 from feature
* 7e59e9b Commit 2 from main
* a282a9d Commit 1 from main
* e315dd5 Initial commit
Note that Commit 3 from feature
is no longer shown as a separate commit because the file it modified was removed during conflict resolution, making its changes empty. If things go wrong or we get confused, we can always stop and reset:
git rebase --abort
Thanks, and happy coding.
Subscribe to my newsletter
Read articles from Raul Naupari directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by

Raul Naupari
Raul Naupari
Somebody who likes to code