As when we work in a new topic (feature or bugfix) it is recommended to keep our branch up-to-date with the target branch (main
, development
, etc.), we can use the git rebase
command instead of git merge
in order to keep our Git history clean.
💡 The Git documentation uses topic branch as a generic term for feature branch and bugfix branch, giving to branches like main
, development
, etc. the name of shared branch because are being used for multiple developers.
The git rebase
command reapplies our commits on top of the target branch, rewriting the Git history. This is not recommended on shared branches because it causes divergence (and therefore the need of conflict solving) and panic on your teammates 😬 since it is sometimes hard to resolve.
The basics
To be clear about how git rebase
works we're going to use the simplest example: you have 3 commits in your topic branch and you want to get the latest changes from main
. To do so you can simply run the following command:
git rebase main
If you're lucky to get no conflicts then you'll have a new Git history with your 3 commits on the top of the main
branch and you just need to override (--force
) the remote branch with your new history.
git push --force origin mytopic-branch
But what if we have conflicts? Well, you're reapplying 3 commits so any of these could bring conflicts. Just resolve conflicts as always and then continue rebasing:
git add .
git rebase --continue
Let's check a more dynamic scenario.
Squashing commits interactively
If you made several commits while you were preparing your work but now you want to combine your commits into one before creating the pull request then you can rebase against your target branch using the --interactive
argument git rebase --interactive main
. A git-rebase-todo
file will be open in the default editor (nano
, vim
, etc.) where you can edit the commands that Git will execute to reapply your commits. Let's check this example:
pick 0680aa7 fix grid responsiveness
fixup 68ab202 fix unit tests
exec npm test
reword 76d14ac fix grid layout for iOS
exec npm test
🧠Thegit-rebase-todo
file is a sequence of commands to be executed by Git, and you can run any shell command using the exec
command.
The pick
is used to take a commit as-is. The commit message is displayed by Git only to help you to identify what changes are there (Git will ignore if you edit it).
Then we have the fixup
command, which combines a specific commit into the previous one without changing the commit message.
If the npm test
fails you will see the following message:
warning: execution failed: npm test
You can fix the problem, and then run
git rebase --continue
Sad time when you need to fix the tests 😢. Before continuing the rebase you will need to commit these changes creating a new commit; or integrating there in the latest one using the classic git commit --amend
.
git add .
git commit --amend
git rebase --continue
The reword
command that we put into the git-rebase-todo
file will open your default editor (e.g. nano) with the current commit message for 76d14ac
. Edit it and save to continue.
💡 The git rebase
reapplies commits, you can do this without needing a target branch (main
): just indicate how many commits you want to reapply for the current branch (HEAD
). For our example of 3 latest commits:
git rebase --interactive HEAD~3
🧠Remember that HEAD
is a pointer to either your current branch or your current commit when you're in a detached HEAD (meaning you are located in a commit not associated with any branch).
And, this is the usage of git rebase --interactive
🎉. Let's continue with the git rebase --exec
.
Do you either prefer rebase
or merge
to keep your branch up to date? 👇 Let me know in the comments.
Conclusion
You can manipulate the commits in a useful way using git rebase
, maybe just using it to keep your work up to date using a linear history, optionally combining your editions into one commit using fixup
.
I hope this guide helps you understand more about Git and how to manipulate your commits safely because you can always git rebase --abort
if the things aren't going how is planned.
In the following post of this series of git rebase
we're going to see how to run tests for the rebased commits automatically. 😬
Top comments (0)