These are the rules that I always followed to keep the git branch clean when I need to work on a big feature that needs more than one sprint and is developed by more than one developer.
Create a parent branch that is dedicated and treated as a copy of the main branch.
The branch will be rebased regularly so it is always up to date with the changes in the main
branch. All of the developers that work on the feature will create and merge their branch from and to this parent branch.
From a content perspective, rebasing is changing the base of your branch from one commit to another making it appear as if you'd created your branch from a different commit.
By rebasing the so-called parent branch regularly, we can avoid complicated conflicts when we merge the parent branch to the main
branch.
How to do it:
git checkout {parent-branch}
git fetch
git rebase origin/main
Adding origin
will be more efficient because after git fetch
, we don’t need to check out the main
branch and pulled all of the changes first.
We can use a story/epic ticket to name our parent branch, or just use one of the ticket cards of the feature so we can always see the overall progress in server preview.
Always keep the child branch up to date with the parent branch.
Because the parent branch will always be changing due to keeping it updated to the main
branch, then, of course, we need it to keep all of the child branches always up to date with the parent branch. Always make sure when the time comes to merge the child branch to the parent, there is nothing like this The source branch is n commit behind the target branch
Sometimes this thing doesn’t cause any problem. But when we work in a big feature with other engineers, better safe than sorry right?
The clean merge request will look like this:
We can rebase the branch daily before we start any work or at the end of the day. Make sure to not be left too behind from the parent branch.
Keep the commit as concise as possible.
With keeping the commit number as little as possible, it will help us if the conflict happens when we try to rebase the branch. But sometimes we worry about losing our progress thus decide to commit little by little that will make our branch has a lot of commits with the same ticket code.
So what we need to do is squash it to become at least one commit per ticket code. The act of "squashing" your commits means that you combine multiple existing commits into a single one. To squash the commits, we can’t simply do git squash
. Instead, we use interactive rebase.
For example, we have these commits that we want to squash into a single one:
What we will do step by step:
git rebase -i HEAD~3
On the command above the number on HEAD~n
is the number of commits we want to squash as one.
Be careful when deciding the n number. Make sure it doesn’t exceed the total commits in the branch or we will mess the branch much worse by including the parent branch commits too.
Then you will see the editor like the image below, pick the top commit, and squash the following commits. p
stands for pick
and s
stands for squash
(look at the red box). After that save and quit the editor.
Then you will be shown another editor like the image below. This editor shows commit messages that will be shown on the squashed commits. You can change it or just leave it. I prefer to leave it as it is so later on, I can still see what commits I squashed.
After squashed successfully, all we need to do is:
git push -f
And then the commit list will be like this:
Keeping the commit number as little as possible will help us if there are too many conflicts happening when we rebase the branch to the parent branch. We can just skip rebasing and do reset the branch and then cherry-pick the commit instead. Cherry-pick one commit is of course much simpler than cherry-pick bunch of commits (we may lose track of which commits we already pick). That’s why I prefer to squash the commits first.
Reset the branch instead of rebasing it when there are too many conflicts.
Like I said before because now we just have one commit, it will be simpler to just reset the branch to the parent branch and cherry-pick the commit when we fall far too behind from the parent branch.
git checkout [child-branch]
git fetch
git reset --hard origin/[parent-branch]
git cherry-pick [hash-commit]
// make sure cherry-pick all of the commits
git push -f
Make sure you already save the hash commits and do git push -f
later to avoid mistakes by pushing it before cherry-picking the commits.
If the conflict still happens, it will be easier to resolve because lesser commits mean lesser time resolving the conflicts.
Top comments (0)