Git 101: Boost your merge speed by avoiding conflicts and merge commits
This post is one of the Git 101: Conquer the GIT POWER series.
Summary:
- Intro
- Update your code every time
- Git pull without merge
- Git merge is bad
- Git rebase is better
- The golden sequence
- Outro
1 - Intro
Short answer: Update the code every time you gonna code with the gold sequence.
In this post, we will learn why is so important to maintain our code updated and how we can do it in a different, a little trickier (but immensely better in long run) approach.
2 - Update your code every time
Some developers are afraid to update their branches with the public branch (master or develop, for example). That fear is justified because it can potentially cause conflicts. But if you wait too much and your branch becomes very outdated, the chance of getting a conflict will become a reality.
To avoid this fate you must update your branch every single time before starting coding. There are some ways to do it, but some approaches are smoother than others.
3 - Git pull without merge
You can make your merges smooth as butter with the git fetch and rebase commands.
The git protocol handles the local and remote changes in different places, so you can safely update the remote code with the command:
git fetch --all
This command only updates the remote references that are inside your machine. Your local references are not touched. It is like git pull, but only the first part. In fact, the git pull command is a combination of the git fetch command followed by the git merge command.
4 - Git merge is bad
When your local branch is outdated, the git pull operation creates a commit that brings all the commits you did before the changes.
Our branch has the new Feature C and D commits. But in the meantime, the remote branch got other commits. When we merge with the remote branch, this happens:
Notice that the hash of Feature D stays the same. But to maintain its hash and the integrity of the remote branch, the git had to create the commit hash(Merge branch 'organize-commits-1' into temp) after the last remote commit (fix: fix feature B).
That git behavior alone is responsible for the majority of the conflicts and confusion we encounter in our daily developer lives.
Notice the "merge remote" commits. They're all created automatically by GIT. The next step will *guarantee that will never happen to your branches again.
5 - Git rebase is better
There are some arguments about how the operation git rebase can cause chaos worse than one thousand merges, and they are correct. Git rebase is an operation you can ONLY use in your private branches, the branches that you and ONLY YOU work with.
I said it before, and I will say it again:
NEVER REBASE A PUBLIC BRANCH
Understood? Ok. Now back at the merges and why rebase do a better job with it.
The git merge combines every commit into a single one and pushes that combined commit to the top of the branch. That leads to different timelines and the horrors that come with it.
The git rebase is better because it reorganizes the commits of your local branch at the top of the commits of the remote branches.
This was made with git merge. The feature D hash doesn't change but will create a commit merge, and that eventually will lead to chaos.
This was made with git rebase. The feature D hash changed but notices how smooth and linear the branch is.
And because the git rebase changes the hashes of commits, it can not be used in public branches. Only your private commits (before the pull request is accepted) can be changed.
But in exchange, you get your code always on top of the development code, which indirectly implies that your branch WILL NEVER conflict when you create the pull request.
6 - The golden sequence
The golden commands to update your code every day are:
git fetch --all
Update everything but not touch the local branches
git checkout my-branch
Go to the branch you want to update.
git checkout -B temp
Create a temporary branch to do the git rebase.
git rebase origin/develop
Update your code with the last changes in develop (or the branch your team uses to group the development code).
git checkout -B my-branch
Go back to your branch and bring the new commit order to it.
git push origin +my-branch
To push force your changes to your private remote branch. NEVER push force public branches.
7 - Outro
Bringing the conflicts to your branch and rebasing your commits on top of the team commit line history are the best ways to dispatch the conflicts swiftly and avoid the merge nightmares. Make sure to use it every day to have peace of mind when making the pull request.